事务
事务是一组原子性的SQL查询,或者独立的工作单元。 要么全部执行成功,要么全部执行失败。
事务的四大特性
- 原子性(atomicity): 事务被视为不可分割的最小工作单元,要么全部成功,要么全部失败。
- 一致性(consistency): 事务从一个一致性状态转换到另一个一致性状态。
- 隔离性(isolation): 一个事务所做的修改在提交之前,对其他事务是不可见的。
- 持久性(durability): 一旦事务提交,所做的修改就会永久保存到数据库中。即使数据库发生故障,数据也不会丢失。
事务的隔离级别
- READ UNCOMMITTED(未提交读): 隔离级别最低, 允许读取尚未提交的数据, 可能会导致脏读、幻读或不可重复读。
- READ COMMITTED(提交读):允许读取已经提交的数据,可以阻止脏读,可能会发生幻读或不可重复读。
- REPEATABLE READ(可重复读): MySQL默认的事务隔离级别。保证同一个事务多次读取的记录结果是一样的, 可以阻止脏读、不可重复读,可能会产生幻读。
- SERIALIZABLE(可串行化): 最高的隔离级别。强调事务串行化执行,避免了脏读、幻读、不可重复读。但是在读取的每一行数据加锁,会导致大量的超时和锁竞争问题。
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|
READ UNCOMMITTED | Y | Y | Y | N |
READ COMMITTED | N | Y | Y | N |
REPEATABLE READ | N | N | Y | N |
SERIALIZABLE | N | N | N | Y |
并发事务带来的问题
- 脏读(Dirty read):一个事务正在访问数据并对数据进行修改,且这种修改还没提交到数据库。 另一个事务也访问了这个数据,并使用这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
- 丢失修改(Lost to modify):一个事务访问了该数据,另一个事务也访问了该数据,第一个事务修改了这个数据,第二个事务也修改了这个数据,这样第一个事务修改的数据被丢失,因此被称为丢失修改。
- 不可重复读(Unrepeatableread):指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
- 幻读(Phantom read):幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
不可重复读和幻读区别:
不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点在于新增或者删除比如多次读取一条记录发现记录增多或减少了。
死锁
指两个或多个事务在同一资源上相互占用,并请求锁定对方占用资源,导致恶性循环现象。
为解决这个问题, 数据库实现死锁检测和死锁超时机制。如InnoDB引擎,处理死锁的方法是,将持有最少行家级的排他锁的事务进行回滚