事务嵌套
-
- 问题产生
回滚事务不生效 -
原因分析
事务里调用的一个方法里面也使用了事务 事务发生了嵌套 当后面的事务创建的时候 mysql会先提交上一个未提交的事务 再开启一个新事务 导致外层事务回滚不生效事务一:startTransaction() -- 开启事务一 a = 0 事务一:query('set a = 1') -- 执行sql a = 1 事务二:startTransaction() -- 提交事务一 开启事务二 a = 1 事务二:query('set a = 2') -- 执行sql a = 2 事务二:commit() -- 提交事务二 a = 2 事务一:rollback() -- 回滚事务一 事务一已提交 a = 2 回滚不生效
-
解决方案
利用mysql的savepoint
事务开启:当事务发生嵌套的时候 不重新开启事务 而是设置一个保存点 保存点序号递增
事务提交:保存点序号递减 只有最外层事务才真正提交
事务回滚:保存点序号递减 回滚到当前的保存点事务一:Qdlib_Util_DB::startTransaction(); -- 开启事务 保存点序号加一 savepoint:0->1 a = 0 事务一:query('set a = 1'); -- 执行sql savepoint:1 a = 1 事务二:Qdlib_Util_DB::startTransaction(); -- 设置保存点 保存点序号加一 savepoint:1->2 a = 1 事务二:query('set a = 2'); -- 执行sql savepoint:2 a = 2 事务二:Qdlib_Util_DB::commit(); -- 保存点序号减一 savepoint:2->1 a = 2 事务一:Qdlib_Util_DB::rollback(); -- 保存点序号减一 回滚事务 savepoint:1->0 a = 0 回滚生效
-
性能分析
事务开启:都是一次交互
事务提交:最外层事务才真正提交 其他提交只是保存点序号减一
事务回滚:都是一次交互
会将提交请求归为一次提交 性能会有提升 循环100次 最外层回滚 其他都为提交 测试结果如下:嵌套层数 用时(s) 内存(kb) 用时降低(%) 内存降低(%) 1 2.05->2.06 138->139 -0.49 -0.72 2 4.43->3.13 268->226 29.35 15.67 3 6.75->4.09 401->301 39.41 24.94 4 8.12->5.52 438->393 32.02 10.27