在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题。

丢失修改

T1T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。

很明显的看出,旺财对A添加的20块不翼而飞了,这就是“数据丢失”,对事务不加任何锁(不存在事务隔离),就会导致这种问题。

读脏数据

操作:写数据的时候添加一个X锁(排他锁),也就是在写数据的时候不允许其他事务进行写操作,但是读不受限制,读不加锁。

这样就可以解决了多个人一起写数据而导致了“数据丢失”的问题,但是会引发新的问题——脏读。

脏读:读取了别人未提交的数据。

不可重复读(读取了提交的新事物,指增删操作)

操作:写数据的时候加上X锁(排他锁),读数据的时候添加S锁(共享锁),而且有约定:如果一个数据加了X锁就没法加S锁;同理如果加了S锁就没法加X锁,但是一个数据可以同时存在多个S锁(因为只是读数据),并且规定S锁读取数据,一旦读取完成就立刻释放S锁(不管后续是否还有很多其他的操作,只要是读取了S锁的数据后,就立刻释放S锁)。

这样就解决了脏读的问题,但是又有新的问题出现——不可重复读。

不可重复读:同一个事务对数据的多次读取的结果不一致。

幻读(读取了提交的新事物,指增删操作)

操作:对S锁进行修改,之前的S锁是:读取了数据之后就立刻释放S锁,现在修改是:在读取数据的时候加上S锁,但是要直到事务准备提交了才释放该S锁,X锁还是一致。

这样就解决了不可重复读的问题了,但是又有新的问题出现——幻读。

例如:

有一次旺财对一个“学生表”进行操作,选取了年龄是18岁的所有行, 用X锁锁住, 并且做了修改。

改完以后旺财再次选择所有年龄是18岁的行, 想做一个确认, 没想到有一行竟然没有修改!

这是怎么回事? 出了幻觉吗?

原来就在旺财查询并修改的的时候, 小强也对学生表进行操作, 他插入了一个新的行,其中的年龄也是18岁! 虽然两个人的修改都没有问题, 互不影响, 但从最终效果看, 还是出了事。

读写锁

读写锁

  • 排它锁(Exclusive),简写为 X 锁,又称写锁。
  • 共享锁(Shared),简写为 S 锁,又称读锁。

有以下两个规定:

  • 一个事务对数据对象 A 加了 X 锁,就可以对 A 进行读取和更新。加锁期间其它事务不能对 A 加任何锁。
  • 一个事务对数据对象 A 加了 S 锁,可以对 A 进行读取操作,但是不能进行更新操作。加锁期间其它事务能对 AS 锁,但是不能加 X 锁。