一、MySQL的事务隔离级别
SQL中定义了4种隔离级别,不同的隔离级别对应着事务中做不同的修改,同时在事务内和事务间的可见性也不同。越低的隔离级别越能支持更高的并发,对系统的开销也越低。
1. read uncommitted (未提交读)
最低级别,允许一个事务读取另一个事务尚未提交的数据。这可能导致脏读、不可重复读和幻读的问题。
在read uncommitted 级别中,当在事务A中对数据的修改即使是在事务未提交的时候,其他并发操作的事务依然可以读取到事务A修改的数据,这种情况我们叫做数据“脏读”。那如果事务A在后面出现回滚的操作时,而其他事务在已经读取到的是事务A之前的修改,就会导致出现数据的修改混乱。
2. read committed (已提交读)
允许一个事务只读取其他已提交事务的数据。这可以避免脏读,但仍可能出现不可重复读和幻读的问题。
在read committed级别中,当一个事务A从开始直到事务提交之前,其他的并发事务对该事务的修改都是不可见的。但是在其他同一事务内执行两次一样的查询时,查询的结果也会不同,所以这个级别同时也叫做不可重复读。
其他大多数的数据库默认的隔离级别都是read committed ,但是mysql 默认隔离级别不是。
3. repeatable read (可重复读)
mysql 默认隔离级别。在一个事务中,多次读取同一数据会得到相同的结果,即使其他事务对该数据进行了修改。这可以避免脏读和不可重复读,但可能出现幻读问题。
“幻读”是指当某个事务在读取某个范围内的记录时另一个事务又在该范围内插入了新的数据,那么再次读取该范围的数据时会出现幻行。
MySQL在存储引擎(InnoDB和XtraDB)下是通过锁机制加MVCC(多版本并发控制)来解决幻读的问题。
因此也是MySQL 中默认使用的事务隔离级别,同时需要使用事务时一般使用InnoDB存储引擎。
4. serializable (可串行化)
最高级别,要求事务串行执行,即事务之间没有并发。可以避免脏读、不可重复读和幻读,但会影响并发性能。
serializable隔离级别是将各个事务强制串行执行,在每个事务执行时都会对该事务影响的数据行进行加锁,因此其他并发的事务则无法进行读写操作,需等这条事务提交后并释放锁才能进行下一个事务的执行。
由于需要对每条数据都加锁,这样就会导致大量的操作超时和锁争用的问题。
在我们的实际项目开发中很少使用这个级别。
————————————————
脏读(Dirty Read):
定义:脏读是指一个事务读取到了另一个事务尚未提交的数据,当那个事务最终回滚时,读取的数据就变得无效或“脏”了。
示例:假设有两个银行账户,Alice 和 Bob。Alice 想要转账给 Bob 1000美元,但在她的事务还没有提交之前,Bob 的查询可能会显示他的余额增加了1000美元。然而,如果 Alice 的事务最终回滚,Bob 实际上并没有得到这1000美元。
不可重复读(Non-Repeatable Read):
定义:不可重复读是指在同一个事务中,多次读取相同数据时,得到了不同的结果。这是因为在事务执行期间,其他事务修改了数据。
示例:假设小明正在查询某本书的价格,结果是50美元。然后,他再次查询,但在这之间,另一个用户购买了这本书并将价格提高到100美元。因此,小明两次查询相同的数据得到了不同的结果,这就是不可重复读。
幻读(Phantom Read):
定义:幻读是指在同一个事务中,多次执行相同的查询,但由于其他事务插入新数据或删除现有数据,每次查询返回的结果集不一样。
示例:考虑一个图书馆数据库,小红正在查询某个作者的所有书籍。第一次查询返回了5本书,但在事务执行期间,另一个用户添加了一本新书,所以在第二次查询时,返回了6本书。这就是幻读,因为查询结果集似乎发生了变化,尽管小红的事务并没有修改任何数据。
标签:面试题,读取,幻读,数据,事务,查询,MySQL,级别 From: https://www.cnblogs.com/Neonuu/p/18120633