0

在使用乐观事务的系统中考虑以下两个 Java 伪代码块。

示例 A

try {
    txn.begin();
    // database operations
    txn.commit();
}
catch (Exception e) {
    txn.rollback();
}

示例 B

txn.begin();
// database operations
try {
    txn.commit();
}
catch (Exception e) {
    txn.rollback();
}

我在我们的代码中看到交易是双向进行的;我确信A是正确的。我的直觉告诉我B是错误的,但是B似乎没有什么坏处,因为commit()它在 try 块中,并且可以在发生错误的情况下被捕获并回滚。请解释B是否正确,为什么。谢谢!

编辑:所以我并没有真正得到我正在寻找的答案。我已经知道B某种程度上是“坏的”,我正在寻找的是它为什么不好;也就是说,是否存在某种可能的情况,A会在B失败的情况下工作?

-tjw

4

2 回答 2

1

我会稍微混合一下(示例 C):

txn.begin(); 
try {
    // database operations
    txn.commit();
}
catch (Exception e) {
    txn.rollback();
}

将您的数据库命令保留在 try 块中,但将“开始”事务排除在外。如果您在“开始”时出错,您将不会尝试回滚从未在 catch 块中启动的事务。

编辑

示例 B 不好的原因,您回滚事务的唯一方法是提交失败。但是,A 也不好的原因是因为您在开始事务时失败的可能性很小,在这种情况下,您将尝试回滚一些不存在的东西。

于 2011-03-22T03:15:21.580 回答
0

好吧,在B中,如果在 commit 之前出现错误,您将不会回滚事务。你也没有提交,至少不是在那段代码中,但也许以后,偶然?尽早提交或回滚似乎更好,并且不要让事务悬而未决以进行一些希望稍后进行的清理。

据说这是B的问题。

此外,根据您的系统,您可能还需要 finally 块来正确解除交易。

于 2011-03-22T03:09:12.583 回答