事务
一:什么是事务
事务是应用程序中一系列严密的操作,一个事务中的一系列的操作要么全部成功,要么一个都不做。
二:事务四大特性
事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
原子性
事务是不可分割,事务中包含的各操作要么都做,要么都不做。
一致性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。
隔离性
一个事务的执行不被其它事务干扰。
持续性
指一个事务一旦成功提交,它对数据库中的数据的改变就应该是永久性的。
三:事务并发处理可能引起的问题
脏读(dirty read):一个事务读取了另一个事务尚未提交的数据,
不可重复读(non-repeatable read) :一个事务的update操作导致另一个事务前后两次读取到不同的数据
幻读(phantom read) :一个事务的操作insert/delete操作导致另一个事务前后两次查询的结果数据量不同。
举例:
事务A、B并发执行时,当A事务update后,B事务select读取到A尚未提交的数据,此时A事务rollback,则B读到的数据是无效的”脏”数据。
当B事务select读取数据后,A事务update操作更改B事务select到的数据,此时B事务再次读去该数据,发现前后两次的数据不一样。
当B事务select读取数据后,A事务insert或delete了一条满足A事务的select条件的记录,此时B事务再次select,发现查询到前次不存在的记录(“幻影”),或者前次的某个记录不见了。
四:解决并发引起的安全性问题:
数据库管理系统(DBMS)采用“锁机制”来实现事务的隔离性(Isolation,其余的A、C、D用日志机制来实现)。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据(并发更新:排它锁):
数据库系统有4个隔离级别,从低到高分别是:未提交读、已提交读、可重复读、串行化。隔离级别用数字表示:1-2-4-8
1、读未提交Read uncommited,可以解决:脏读。
不添加共享锁。分为2种情况:
①情况1:事务B可以在事务A对记录的读取过程中修改同一记录,可能会导致事务A读取的数据是一个被破坏的或者是不完整不正确的数据。
②情况2:在事务A中可以读取到事务B中修改过的数据,但此时事务B尚未提交。可能会发生的问题就是脏读。
2、已提交读Read commited,问题:不可重复读。
在事务A中读取数据时对记录添加共享锁,待读取结束后才会立即释放该锁。那么事务B对该数据的修改要一直等待,直到A中的读取过程结束,但不是整个事务A的结束。所以,可能发生的问题就是事务A在不同阶段对同一记录的读取结果可能是不同的。
3、可重复读Repeatable read,问题:幻读。
对于读出的记录,添加共享锁直到事务A结束。事务B试图对这个记录的修改会一直等待,直到整个事务A结束。InnoDB 默认的事务隔离级别就是可重复读。可能发生的问题:当执行一个范围查询时,可能会发生幻读(解决幻读的方法:增加范围锁RangeS,锁定检索范围为只读,这样就避免了幻读)。
4、串行化Serializable,问题:没有问题,上述3种级别中的脏读、不可重复读、幻读都不会发生。
添加范围锁(比如表锁,页锁等),直到事务A结束。以此阻止事务B对此范围内的修改操作。