1

我已经创建了一个设置ConnectionCustomizerautoCommit隔离false级别TRANSACTION_REPEATABLE_READonCheckOut()

当我在我的 psotgresql DB 上执行 CRUD 操作然后提交时,事务没有提交,我可以在 pg_log 中看到回滚(见底部)。

我读过 c3p0 默认行为是在连接返回池时回滚任何未提交的事务。我怎样才能真正提交我的交易?

我已将此示例代码写入资源进行测试:

@GET
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public Response test(@QueryParam("userId") long userId,
                     @HeaderParam("Accept-Language") String acceptLanguage) throws NamingException, SQLException {

    InitialContext context = new InitialContext();
    ComboPooledDataSource dataSource = (ComboPooledDataSource) context.lookup("jdbc/mydb");

    SimpleJdbcInsert insertTest = new SimpleJdbcInsert(dataSource)
                                            .withTableName("chat")
                                            .usingGeneratedKeyColumns("idchat");
    //BEGIN transaction                                     
    dataSource.getConnection().commit();

    Map<String, Object> parameters = new HashMap<String, Object>(2);
    parameters.put("idcompte", userId);
    parameters.put("idvendeur", 148);
    parameters.put("idannonce", 282);
    parameters.put("creationdate", new Timestamp(Calendar.getInstance()
            .getTime().getTime()));
    parameters.put("lastmodified", new Timestamp(Calendar.getInstance()
            .getTime().getTime()));

    Map<String, Object> m = new HashMap<String, Object>();

    m.put("idchat", insertTest.executeAndReturnKey(parameters));

    //Commit transaction
    dataSource.getConnection().commit();

    return Response.ok(m, MediaType.APPLICATION_JSON).build();
}

此资源返回我自动生成的值:

{
    idchat: 101
}

但是当我查看表格时,没有插入该行并且 pg_log 显示了这一点:

LOG:  durée : 0.019 ms, analyse <unnamed> : SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
LOG:  durée : 0.005 ms, lien <unnamed> : SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
LOG:  durée : 0.006 ms  exécute <unnamed>: SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
LOG:  durée : 0.014 ms, lien S_1 : BEGIN
LOG:  durée : 0.004 ms  exécute S_1: BEGIN
LOG:  durée : 0.222 ms, analyse <unnamed> : INSERT INTO chat (idannonce, idcompte, idvendeur, creationdate, lastmodified) VALUES($1, $2, $3, $4, $5) RETURNING "idchat"
LOG:  durée : 0.075 ms, lien <unnamed> : INSERT INTO chat (idannonce, idcompte, idvendeur, creationdate, lastmodified) VALUES($1, $2, $3, $4, $5) RETURNING "idchat"
DÉTAIL:  paramètres : $1 = '282', $2 = '226', $3 = '148', $4 = '2013-07-04 14:57:07.466', $5 = '2013-07-04 14:57:07.466'
LOG:  durée : 1.027 ms  exécute <unnamed>: INSERT INTO chat (idannonce, idcompte, idvendeur, creationdate, lastmodified) VALUES($1, $2, $3, $4, $5) RETURNING "idchat"
DÉTAIL:  paramètres : $1 = '282', $2 = '226', $3 = '148', $4 = '2013-07-04 14:57:07.466', $5 = '2013-07-04 14:57:07.466'
LOG:  durée : 0.012 ms, lien S_2 : ROLLBACK
LOG:  durée : 0.030 ms  exécute S_2: ROLLBACK
LOG:  durée : 0.025 ms, analyse <unnamed> : SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
LOG:  durée : 0.004 ms, lien <unnamed> : SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
LOG:  durée : 0.006 ms  exécute <unnamed>: SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ
4

1 回答 1

2

您正在从 DataSource 获取一个新的 Connection 并在其上调用 commit() 。那没用,因为您没有在新的 Connection 上做任何工作。JDBC 事务的范围是每个连接。您需要在执行插入的 Connection 上执行 commit(),对它的访问隐藏在insertTest对象的某个位置。

(编辑,一个名为的类SimpleJdbcInsert可能不是一个好主意。JDBC 插入非常简单。如果您只是在这里完成工作,或者将其交给接受连接的辅助函数,您的代码会干净得多。如果您正在处理数据源,您SimpleJdbcInsert必须负责所有获取连接、提交或回滚任何事务工作以及关闭()连接。如果该对象无法关闭()连接,则您有连接泄漏并且会耗尽池。如果它在没有提交的情况下关闭()连接,你不应该因为你的工作被回滚而感到震惊。)

于 2013-07-04T13:35:01.113 回答