简介:事务是一条或多条数据库操作的集合,在事务中的操作,要么都执行修改,要么都不执行。
事务的四大性质即ACID
A(atomicity)原子性:一个事务的执行被视为一个不可分割的最小单元。事务里面的操作,要么全部成功执行,要么全部失败回滚,不可以只执行其中的一部分。
C(consistency)一致性:一个事务的执行不应该破坏数据库的完整性约束。
I(isolation)隔离性:事务之间相互独立,互不干挠。
D(durability)持久性:事务提交之后,需要将提交的事务持久化到磁盘。即使系统崩溃,提交的数据也不应该丢失。
事物的隔离级别
事物的隔离级别主要分为四种,即
Read uncommitted(读未提交):事务中的修改,即使没有提交,在其他事务也都是可见的。结果:产生脏读。
Read committed(读已提交):一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读,因为在一个事物中执行多次相同的查询,可能会得到不一样的结果。因为在这多次读之间可能有其他事务更改这个数据,每次读到的数据都是已经提交的。结果:产生不可重复读。
Repeatable read(可重复读):解决了脏读,也保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题,指的是当某个事务在读取某个范围内的记录时,另外一个事务也在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行。结果:产生幻读。
Serializable(可串行化):它通过强制事务串行执行,避免了前面说的幻读的问题,但由于读取的每行数据都加锁,会导致大量的锁征用问题,因此性能也最差。
隔离级别 | 产生脏读 | 产生不可重复读 | 产生幻读 |
读未提交 | √ | √ | √ |
读已提交 | × | √ | √ |
可重复读 | × | × | √ |
串行化 | × | × | × |
下面首先谈一谈 可重复读
从两个方面探究
1. 如何避免了不可重复读:
首先,不可重复读是因为在一个事物中执行多次相同的查询,可能会得到不一样的结果。因为在这多次读之间可能有其他事务更改这个数据,每次读到的数据都是已经提交的。
那么可重复读是如何避免了这个问题呢?原来是因为事物在执行查询时,对检索的数据(范围性)都加了行锁(LOCK),这样其他事物就无法对这些加了锁的数据进行更改,自然避免了同一事物多次查询数据不一致的问题。
2. 为什么会产生幻读:
指的是当某个事务在读取某个范围内的记录时,另外一个事务也在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行。
上面谈到如何避免不可重复读,是因为对检索到的数据加了锁,但是并没有阻止别的事物在这些数据行中间插入新的数据行,导致同一事物多次查询时,突然发现多出来一行或几行数据(幻行)。这就是所谓的幻读。
当下,热门的几大数据库如
SQL Server、Oracle 都采用的是第二隔离级别:读已提交。
MySQL 采用的是 可重复读。
转载请注明来源。