1.什么是事务
大家都是好兄弟,同生共死!
是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元)
2.事务的四大特性
原子性 | 事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做 |
一致性 | 事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。 |
隔离性 | 一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。 |
持续性 | 也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。 |
3.事务的隔离级别
数据库在并发访问会存在如下问题:
脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
例:当一个事务 T1 正在多次修改某个数据,而在这个事务 T1 中这多次的修改都还未提交,这时一个并发的事务 T2 来访问该数据,就会造成两个事务得到的数据不一致。
因为 T1 正在修改数据,T2 读取的是没有提交的数据,所以 T2 读取的数据是脏数据,
不可重复读:不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
例:事务 T1 在读取某一数据,而事务 T2 立马修改了这个数据并且提交事务给数据库,事务T1 再次读取该数据就得到了不同的结果,发送了不可重复读。
T1 先读取数据,可是事务还没提交,T2 过来修改了这条数据,导致 T1 再次读取的数据和之前不同。
幻读:幻读是事务非独立执行时发生的一种现象。
例:事务 T1 对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务 T2 又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务 T2 中添加的,就好像产生幻觉一样,这就是发生了幻读。
针对以上问题,数据库有四种隔离级别进行解决。
1.Read Uncommitted(读取未提交内容)
所有事务都可以看到其他未提交事务的执行结果。
这会导致事务 B 会读取到事务 A 中的未提交的结果,导致事务 B 发生脏读。
2.Read Committed(读取提交内容)
一个事务只能看见已经提交事务所做的改变。
事务 B 无法读取到事务 A 中的数据了,所以不会有脏读问题。不过如果事务 B 把事务 A 读取的数据修改了,会导致事务 A 发生两次读取数据结果不一致问题,导致不可重复读。
3.Repeatable Read(可重读)
它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。
会锁住事务 A 正在读取的某行数据,这时候事务 B 可以读取数据,却无法修改数据了,解决了不可重复读问题。不过同样,如果事务 B 不修改数据,而是在数据库表中插入一条新的数据,那么对于事务 A 如果之前针对全表进行了更新,在事务 B 新增数据后,发现还有数据没有更新,好像之前全表读取的数据不正确,因此会导致幻读问题。
4.Serializable(可串行化)
最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。
会锁住事务 A 查询的表或者记录行,此时事务 B 只可以读取这些记录,而无法修改这些记录。