什么是事务
事务是一系列操作构成的一个执行单元。这些操作可以是插入、删除、更新或查询,它们要么全部执行,要么全不执行。
事务特征(ACID)
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
原子性
原子性其实就是把事务的定义又表述了一遍,强调同一个事务中的操作只能全部成功或全部失败,不能部分成功。全部失败是要回到执行之前的状态。
一致性
比较正式的说法是事务执行(成功或回滚)后,数据库的完整性约束没有被破坏。
一方面是数据库本身的约束,比如唯一键约束,外键约束等,这些不需要我们操心,数据库自身会保证。
另一方面是数据一致性。所谓此消彼长,能量既不会凭空产生,也不会凭空消失,它只会从一种形式转化为其他形式,或者从一个物体转移到另一个物体,而在转化和转移的过程中,能量的总量保持不变,这就是能量恒守定律。一致性也是如此。
隔离性
隔离性指并发执行的事务之间不能互相干扰。隔离性并不是事务执行上的完全隔离,而是值事物间影响的隔离,如果两个事务之间不会相互影响,也就不需要隔离了。原子性和隔离性都是为了保证一致性。
持久性
这里的持久性不是你们想象的持久性,它是指事务完成以后,它所带来的影响将永久存在于数据库中,不会被回滚,断电重启也还在。
为什么要隔离
一是因为事务不是单一操作,而是一些列操作;二是因为事务会并发执行。如果事务没有隔离,那么并发执行的结果将是不可预知的。
事务隔离级别
隔离级别一共4个,由低到高依次是读未提交、读提交、可重复读、串行。根据掐头去尾原则,读未提交和串行一般是不用的。我也不懂为什么万年不用的东西还要存在。
读未提交
这是最低的隔离级别,它允许一个事务读取其他事务还未提交的内容。由于还未提交,所以就可能回滚,这样导致的问题叫脏读。
读提交
这是多数数据库的默认隔离级别,它限制了一个事务要等另一个事务提交后才能读取数据。如果一个事务里有两个读取操作,而这两个读取操作之间有一个包含更新操作的事务提交,就会导致两次读取的内容不一致,这就叫不可重复读。不可重复读指的是在同一个事务中重复读取的内容不一致。
可重复读
这是MySQL的默认隔离级别,它规定读数据的事情开启后不允许修改操作。因为可重复读只是不允许修改,但是可以插入。如果在两次范围读取中,有另一个事务插入了数据,那么这两次范围读取的内容也会不一致,这次取名叫幻读。
串行
这是最高的隔离级别,事务之间串行执行。它不会出现脏读、不可重复读和幻读,但是一般也不用。一是因为效率低,二是事务之间有并发的可能性,并不是所有事务之间都必须隔离,虽然会有一些问题,但是实践告诉我们,问题不大。
至此你会发现事务隔离中的问题都发生在两次读操作中。
两次读取之间,被读的数据回滚,就是脏读。
两次读取之间,被读的数据更新,就是不可重复读。
两次读取之间,插入新数据,就是幻读。
随着隔离级别的提高,就是在依次解决以上三个问题。