数据库事务
事务是数据库中经常碰到的一个概念,总结一下相关知识,汇总对事务的理解。
什么是事务
事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务的四大特性ACID
- 原子性(Atomicity):事务是最小的操作单位,不允许再分割,原子性确保了操作要么都执行要么都不执行。
- 一致性(Consistency):事务执行前后数据保持一致。理解上就是一个基本的转账操作,执行前后总额不变,不能多或少了。
- 隔离性(Isolation):并发访问数据库时,一个用户的事务不能被其它事务干扰。
- 持久性(Durability):事务提交后,对数据库中的数据的改变是持久的,即使数据库出现故障也不应该对其有任何影响。
并发事务带来的问题
为了提高性能,并发是必须的,多个事务经常会操作相同的数据来完成各自的任务,但会引发相关的问题:
- 脏读(dirty-read):一个事务修改了数据但还没进行提交,这时另一个事务则读取并使用了该数据,这就是脏读。这个数据可能只是一个中间结果,未提交前都是不准确的,依据这样的数据做的处理都是不正确的,对于另一个事务而言,这个数据就是“脏数据”。
- 丢失修改(lost to modify):一个事务修改了某个数据,然后另一个事务也紧接着进行了修改,这样第一个事务的修改结果就会丢失。
- 不可重复读(Unrepeatable read):一个事务内多次读取同一个数据,事务未结束时,另一个事务对该数据进行了修改,那么第一个事务在两次读取之中,读到了不一样的数据。
- 幻读(phantom read):与不可重复读类似,一个事务多次读取多行记录时,另一个事务插入或删除了几行数据,导致第一个事务两次读取之中,读到了不一样的数据。
不可重复读和幻读的区别
不可重复读的重点是某行记录的修改,例如:多次读取某个数据,发现数据被修改了。
幻读的重点是多行记录的新增或删除,例如:多次读取数据,返现记录增加或者减少了。
事务的四个隔离级别
SQL标准定义了四个隔离级别
读取未提交(read-uncommitted):最低的隔离级别,允许读取尚未提交的数据变更,无法防止:脏读、不可重复读和幻读。
读取已提交(read-committed):允许读取事务已经提交的数据,可以防止脏读,但是仍无法防止:不可重复读和幻读。
可重复读(repeatable-read):对同一个数据的多此读取结果都是一样的,除非是被本身的事务所修改,可以防止:脏读、不可重复读,但是仍无法防止:幻读。
串行化(serializable):最高的隔离级别,所有事务逐个执行,这样事务间就不会互相干扰,但是性能也是最差的,可以防止:脏读、不可重复读以及幻读。
*隔离级别* | *脏读* | *不可重复读* | *幻读* |
---|---|---|---|
READ-UNCOMMITTED | √ | √ | √ |
READ-COMMITTED | × | √ | √ |
REPEATABLE-READ | × | × | √ |
SERIALIZABLE | × | × | × |