数据库的隔离级别
数据库的四大特性
-
原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。 -
一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。 拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。 -
隔离性(Isolation)
多个并发事务之间要相互隔离,一个事务不能被其他事务的操作所干扰。 -
持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
数据库的隔离级别
- Read uncommitted (读未提交)
- Read committed(读已提交)
- Repeatable read(可重复读)
- Serializable (串行化)
数据库隔离级别解决的问题
-
脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
示例:A在一个事务里,往T1表里插入了一条记录,此时B另起一个事务,查询T1表可以看到该记录,之后A回滚事务,B在没有关闭事务的情况下,发现该记录消失了。 -
不可重复读
不可重复读是指,在一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
示例:A在一个事务里,查询表T1的某个字段,此时B修改了T1表的这个字段,A再次查询时,发现该字段发生了变化。 -
幻读
幻读是指,在一个事务执行批量修改时,有新的数据插入,就好像批量修改没玩完成一样。
示例:A在一个事务里,批量把表T1的某字段从1更新为2,此时B恰好往T1表里插入了一条字段为1的记录。A在执行完操作发现还有一条没修改。
很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。
如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复 读了。
但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。