为了保证一系列相互关联的数据在修改前后相一致而不出现矛盾的情况,在软件系统中引入了事务(Transaction)概念。
事务的隔离就是对不同的事务之间不会互相影响的要求。
锁
显而易见的实现方法就是加锁。
根据不同的规则,锁分为三种:
- 写入锁(Write lock,独占锁,eXclusive lock)
- 表明目标数据正在被写入,所以其他事务不能再对目标获取读取锁。(不能获取读取锁不代表不能读取。)
- 同时只能有一个事务获取写入锁(因此也叫独占锁)。
- 读取锁(Read lock,共享锁,Shared lock)
- 表明目标数据正在被读取,此时其他事务不能获取写入锁。(如果此时有且仅有一个事务获取了读取锁,也可以选择升级为写入锁。)
- 可以同时被多个事务获取(因此也叫共享锁)。
- 范围锁(Range lock)
- 对一个范围内的数据施加的独占锁,没有锁就不能更新其中的数据,也不能在此范围内增删数据。
隔离级别
下列隔离级别是从上到下递进的关系,更高的隔离级别避免了较低级别的问题。但隔离级别越高吞吐量越低,所以一般要按需选择确定隔离级别。
读未提交(Read uncommited)
是最低的隔离级别,只在写时加写锁,写完释放。
问题:脏读(Dirty read),即一个事务可能读到别的事务还没提交的数据。
读已提交(Read commited)
读已提交=读未提交+读时要加读锁,读完立即释放。
问题:不可重复读(Non-repeatable read),即一个事务中先后执行两次对某一数据的查询有可能读到不同的数据。(例如有另一个事务在这期间提交了更改。)
可重复读(Repeatable read)
可重复读=读已提交+读时加读锁,直到事务结束后才释放。
问题:幻读(Phantom reads),即一个事务中先后执行两次查询得到不同的结果集。(因为即使施加了写入锁,在对应的范围内增删数据也是允许的。)
可序列化(Serializable)
可序列化=可重复读+当查询时必须加范围锁,事务结束后释放。
这是最高的隔离级别,解决了上述三种级别中存在的问题。
发表回复