mib*_*lma 5 sql orm transactions h2 ormlite
我正在使用ORMLite访问Java中的h2数据库.要执行事务,我使用的是静态方法TransactionManager.callInTransaction.
在单个独立交易的情况下,这工作正常.但是,如果事务彼此嵌套,则即使外部事务失败,内部事务也会被提交.
就像在这段伪代码中一样:
OuterDatabaseTransaction
{
Loop
{
InnerDatabaseTransaction
{
//Multiple update or create statements
//One of the InnerDatabaseTransactions throws a random exception
}
//Alternatively the OuterDatabaseTransaction throws a random
//exception but all commited InnerDatabaseTransactions should rollback still
}
}
Run Code Online (Sandbox Code Playgroud)
所以我期望的是,如果任何内部事务失败,外部事务也会失败.如果外部事务失败,则没有任何内部事务被提交.目前似乎每个内部事务都是单独提交的,并且例如不与外部事务共享相同的Savepoint.
更新(谢谢)
查看跟踪显示以下内容
[TRACE] JdbcDatabaseConnection connection is closed returned false
[TRACE] JdbcDatabaseConnection connection autoCommit is true
[TRACE] JdbcDatabaseConnection connection set autoCommit to false
[DEBUG] TransactionManager had to set auto-commit to false
[TRACE] JdbcDatabaseConnection save-point sp14: id=0 name=ORMLITE15 set with name ORMLITE15
[DEBUG] TransactionManager started savePoint transaction ORMLITE15
[TRACE] JdbcDatabaseConnection connection is closed returned false
[TRACE] JdbcDatabaseConnection connection autoCommit is false
[TRACE] JdbcDatabaseConnection save-point sp15: id=0 name=ORMLITE16 set with name ORMLITE16
[DEBUG] TransactionManager started savePoint transaction ORMLITE16
[TRACE] JdbcDatabaseConnection connection is closed returned false
[TRACE] JdbcDatabaseConnection update statement is prepared and executed returning 1: <...>
[DEBUG] BaseMappedStatement update data with statement <...> changed 1 rows
[TRACE] BaseMappedStatement update arguments: <...>
[TRACE] JdbcDatabaseConnection connection is committed for save-point ORMLITE16
[DEBUG] TransactionManager committed savePoint transaction ORMLITE16
-> [ERROR] TransactionManager after commit exception, rolling back to save-point also threw exception
[TRACE] JdbcDatabaseConnection connection set autoCommit to true
[DEBUG] TransactionManager restored auto-commit to true
[TRACE] JdbcDatabaseConnection connection is closed returned false
Run Code Online (Sandbox Code Playgroud)
进入源代码会发现,在回滚OuterDatabaseTransaction期间,异常会在下面函数中的org.h2.engine.Session.java中的h2源中抛出.背后的原因然而我还不明白.
private void checkCommitRollback() {
if (commitOrRollbackDisabled && locks.size() > 0) {
throw DbException.get(ErrorCode.COMMIT_ROLLBACK_NOT_ALLOWED);
}
}
Run Code Online (Sandbox Code Playgroud)
更新2
要查找原因,您可以打开跟踪级别日志记录。工作嵌套事务应生成如下日志:
TRACE: connection supports save points is true
TRACE: save-point <...> set with name ORMLITE1
DEBUG: started savePoint transaction ORMLITE1
...
TRACE: save-point <...> set with name ORMLITE2
DEBUG: started savePoint transaction ORMLITE2
...
TRACE: connection is committed for save-point ORMLITE2
...
TRACE: save-point <...> set with name ORMLITE3
DEBUG: started savePoint transaction ORMLITE3
...
TRACE: save-point ORMLITE3 is rolled back
...
TRACE: save-point ORMLITE1 is rolled back
Run Code Online (Sandbox Code Playgroud)
在此示例中,ORMLITE1 是外部事务的保存点,ORMLITE2 和 ORMLITE3 用于内部事务。第一个内部事务最初被提交,第二个事务回滚到 ORMLITE3 并导致外部事务回滚到 ORMLITE1,它又隐式取消了第一个内部事务。
但如果你在日志中看到这样的内容:
TRACE: connection supports save points is false
Run Code Online (Sandbox Code Playgroud)
那么 JDBC 驱动程序不支持保存点,并且嵌套事务将无法工作。理论上这不应该发生,因为 H2 声明支持保存点。
如果你看到这个:
ERROR: after commit exception, rolling back to save-point also threw exception
Run Code Online (Sandbox Code Playgroud)
然后回滚到保存点由于某种原因失败。检查你是否使用相同的ConnectionSource在外部和内部交易中使用相同的内容。
或者您在日志中发现了导致问题的其他内容。此外,将日志附加到您的问题可能会有所帮助。我建议用真正的Java代码替换伪代码。
以下是您收到的错误的官方描述:
提交_回滚_不允许= 90058
如果对象被锁定,则尝试在触发器内调用提交或回滚,或者尝试调用触发器内隐式提交当前事务的方法时,会引发代码 90058 的错误。这并不是因为它会过早释放锁。
链接:http ://www.h2database.com/javadoc/org/h2/constant/ErrorCode.html#c90058
也许这将帮助您进一步找到问题的原因。对我来说,很难说更多没有看到你的代码。祝你好运!
| 归档时间: |
|
| 查看次数: |
1881 次 |
| 最近记录: |