隔离级别
MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ)。
- 未提交读(READ UNCOMMITTED)。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(会有脏读问题)。存在脏读,事务A读取了事务B已经修改但尚未提交的数据。若事务B回滚数据,事务A的数据存在不一致性的问题。
- 提交读(READ COMMITTED)。本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(会有不重复读)。存在事务先后两次读到的数据结果可能会不一致的情况,事务A读取了数据后,再次读取会读取到事务B提交的新数据,即读取的数据前后发生了改变。
- 可重复读(REPEATABLE READ)。在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是幻觉。
- 串行化(SERIALIZABLE)。强制事务串行执行,避免幻读问题。简单说就是在读取的每一行数据上都加上锁,所以可能出现大量的超时和锁竞争的问题。现实中很少使用到这个级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,可考虑使用。[
](https://blog.csdn.net/m0_38143375/article/details/102625510)
死锁
死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。
InnoDB存储引擎,能检测到死锁的循环依赖,并立即返回一个错误。将持有最少行级排他锁的事务进行回滚
事务提交
MySQL默认采用自动提交(AUTOCOMMIT)模式。也就是说,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作。可以通过设置AUTOCOMMIT变量来启用或者禁用自动提交模式:set autocommit=1
1或者ON表示启用,0或者OFF表示禁用。当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显式地执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时又开始了另一个新事务。
对非事务型的表,比如MyISAM或者内存表,不会有任何影响,一直处于AUTOCOMMIT启用的模式。
对于UPDATE、DELETE和INSERT语句,InnoDB会自动开启事务并给涉及数据集加排他锁,并且默认自动提交事务,而不是说在事务中使用这些语句才自动加锁;对于普通SELECT语句,InnoDB不会加任何锁,所以即使数据加上了排他锁,普通select语句还是可以查询到,而select语句(加锁)和UPDATE、DELETE、INSERT(自动加锁)会被阻断。
普通select语句显示的加锁:
共享锁:select * from tableName where … + lock in share mode排他锁:select * from tableName where … + for update
