哪个应该在回滚,App或DB上主动完成任务?

时间:2010-07-23 10:41:28

标签: mysql database transactions rollback acid

MySql InnoDB设置为autocommit off并使用默认隔离级别REPEATABLE READ。有两种情况,两个不同的事务T1和T2在下面的时间序列中运行,

1)

time    T1                  T2

t1  update row 1->OK
t2                      update row 2->OK
t3  update row 2->wait->timeout error
t4  commit or rollback or retry t3

T1在t3获得超时错误,因为它无法抓住第2行上的T2尚未释放的写锁定,然而,如果T1在t4提交它会导致T1的“部分”更新,即第1行是更新但第2行没有,因此这种做法违反了ACID的“原子性”规则。

根据ACID的“原子性”规则,交易应该“完成”成功或失败,但不能部分成功。

APP必须要求T1回滚或者在t3接收到错误之后在t4提交之前重试超时更新直到成功,从而实现原子性规则。

2)

time    T1              T2

t1  update row 1->OK
t2                  update row 2->OK
t3  update row 2->wait
t4                  update row 1-> DB detects deadlock then forces T2 rolled back
      wait->OK

1)数据库只向APP发送超时错误,由APP决定是否回滚T1,但在2)不仅DB检测到死锁错误,而且还用于滚动可能的死锁T2

理论上,在1)DB也可以用来回滚T1,但在2)DB可能只取消导致死锁然后向APP发送死锁错误的操作,由APP决定回滚T2或者不

问题在于,在DB级别上首先检测到错误时,DB选择具体条件来选择APP或其自身是否应该处理回滚。

非常感谢!

1 个答案:

答案 0 :(得分:2)

回滚应始终由客户端应用程序处理,数据库。客户端可能正在执行许多不同的操作作为单个“工作单元”,因此,客户端应该可以控制何时将该工作投入数据库或回滚。

<强>参考
你可以参考Tom Kyte的这个helpful link,他对这个问题非常强烈,他甚至建议从PL / SQL中删除提交/回滚(Oracle的程序语言;我知道你的数据库是mysql,但概念仍然是相同)。

  

另一个引人注目的原因   客户端应用程序,唯一的事情   这真的可以控制交易   流,应该

     

a)提交或b)回滚

     

它的工作。 (连同触发器,   自治交易和何时   其他人,我会放弃提交   如果我按照自己的方式在plsql中回滚   :)