数据库事务设计问题

时间:2011-03-22 02:51:27

标签: database transactions optimistic-concurrency

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

示例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

2 个答案:

答案 0 :(得分:1)

我会稍微混合(例C):

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

将数据库命令保留在try块中,但保留“begin”事务。如果您在'begin'上出错,则不会尝试回滚从未在catch块中启动的事务。

修改

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

答案 1 :(得分:0)

好吧,在 B 中,如果在提交之前出现错误,则不会回滚事务。你也没有提交,至少不是在那段代码中,但可能是后来,偶然的?尽可能早地提交或回滚似乎更好,并且不要让事务处于闲置状态,以便稍后进行一些清理。

它说这是 B 的问题。

此外,根据您的系统,您可能还需要最终阻止以正确解除交易。