普通事务
以 begin / start transaction 开始,commit / rollback 结束的事务。或者是带有保存点 savepoint 的事务。
2. 链式事务
一个事务在提交的时候自动将上下文传给下一个事务,也就是说一个事务的提交和下一个事务的开始是原子性的,下一个事务可以看到上一个事务的处理结果。MySQL 的链式事务靠参数 completion_type 控制,并且回滚和提交的语句后面加上 work 关键词。
3. 嵌套事务
有多个 begin / commit / rollback 这样的事务块的事务,并且有父子关系。子事务的提交完成后不会真的提交,而是等到父事务提交才真正的提交。
4. 自治事务
内部事务的提交不随外部事务的影响,一般用作记录内部事务的异常情况。MySQL 不支持自治事务,但是某些场景可以用 MySQL 的插件式引擎来变相实现。
工作中有使用Mybatis,碰到一种情况。
排查中有两个问题先要明确
参考 http://blog.csdn.net/hupanfeng/article/details/9238127 分析Mybatis源码,可以发现一个session 对应着一个连接MySQL连接,所以嵌套的session应该是两个事务。并且batchexcutor模式下,session.flushstatement的时候,才会去写入mysql io中,也就是执行flush的时候,才会在mysql server端查询到该事务。
同时MySQL中也不存在事务嵌套的说法,其事务提交的情况说明如下:
autocommit是对于一个连接session来说,默认情况下,一个新的session里,autocommit=1
autocommit=1时候,
如果没有begin, 一条sql语句就是一个事务,即任务要么被提交、要么失败回滚。
如果有begin,则无视了autocommit设置,走begin显式事务的规则。
autocommit=0时候,
则即使你不显示得begin,你的sql也在begin块里,即已经处在一个事务里了。
完全按照begin开始的事务的方式处理。
begin:
begin ----------- 1
sql1
sql2
sql3
commit --------------- 2
这是一个标准的显式事务块。
除去autocommit=1一条sql组成一个事务块之外
但是在某些情况下1,2都可以不显式的标识。
事务开始:
begin,
autocomit=0 ,当前不在事务中则默认开启一个事务
事务commit:
commit
一些mysql规定的语句,如begin等。e Section 14.3.3, “Statements That Cause an Implicit Commit”.
所以刚两个事务卡在哪里了?
事务1 在索引上2上删除了数据,导致锁住next-key锁,
事务2 在索引2上插入,需要访问next-key ,锁超时,事务失败。
具体参见超赞的博文: http://tech.meituan.com/innodb-lock.html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)