mysql事务出错后会自动回滚吗?不会!
前言:看到好几篇博客都是说会,不过他们要么没打开read uncommitted级别,要么是直接关闭会话后,再查询的。对于前者,不管事务出错后是否回滚,在默认隔离级别下都是读取不到的,并不能证明结论。对于后者,事务出错后直接将会话关闭,那么在close之前是会自动rollback的,不管事务是否出错,都是这样,这也不能证明事务出错后会自动回滚。
首先,开启一个会话,在会话中建立事务A,插入两条记录如下:
此时,第二条插入语句出错,事务会自动回滚吗?
再开启另一个会话,建立事务B,查询记录:
此时发现表中没有记录,是否证明事务A自动回滚了呢?
其实不然,mysql中事务隔离级别默认为read repeatable,所以事务B不能读取事务A未提交的内容,不管事务A中语句是否出错,或者出错后是否自动回滚,事务B都是读取不到的。
此时为了完成实验,需要将事务B的隔离级别改为read uncommitted。然后读取记录:
你会发现,此时是能读取事务A中没出错的那条插入记录的。
那么我们在事务A中手动回滚看看?
事务A:
事务B:
事务A中rollback后,事务B什么都读取不到了。(此时,如果直接将事务A的会话关闭,事务B也是读取不到的,原因在于close之前会自动rollback没提交的事务,无论事务是否报错)
事实证明事务出错后,不会自动回滚。
如果你在事务出错后,直接提交或者开启一个新事务(开启新事务会自动提交先前的事务),那么先前的一条插入记录会写入数据库,此时会违背了事务的原子性,一部分做了,一部分没做。