数据库的并发 *** 作可能带来哪些问题 丢失更新 死锁 违反唯一性约束

数据库的并发 *** 作可能带来哪些问题 丢失更新 死锁 违反唯一性约束,第1张

数据库中常见的并发 *** 作所带来的一致性问题包括:丢失的修改、不可重复读、读脏数据、幻影读(幻影读在一些资料中往往与不可重复读归为一类)。

丢失修改

下面先来看一个例子,说明并发 *** 作带来的数据的不一致性问题。

考虑飞机订票系统中的一个活动序列:

甲售票点(甲事务)读出某航班的机票余额A,设A=16.

乙售票点(乙事务)读出同一航班的机票余额A,也为16.

甲售票点卖出一张机票,修改余额A←A-1.所以A为15,把A写回数据库.

乙售票点也卖出一张机票,修改余额A←A-1.所以A为15,把A写回数据库.

结果明明卖出两张机票,数据库中机票余额只减少1。

归纳起来就是:两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。前文(2.1.4数据删除与更新)中提到的问题及解决办法往往是针对此类并发问题的。但仍然有几类问题通过上面的方法解决不了,那就是:

不可重复读

不可重复读是指事务T1读取数据后,事务T2执行更新 *** 作,使T1无法再现前一次读取结果。具体地讲,不可重复读包括三种情况:

事务T1读取某一数据后,事务T2对其做了修改,当事务1再次读该数据时,得到与前一次不同的值。例如,T1读取B=100进行运算,T2读取同一数据B,对其进行修改后将B=200写回数据库。T1为了对读取值校对重读B,B已为200,与第一次读取值不一致。

事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录神密地消失了。

事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。(这也叫做幻影读)

读"脏"数据

读"脏"数据是指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤消,这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据就为"脏"数据,即不正确的数据。

产生上述三类数据不一致性的主要原因是并发 *** 作破坏了事务的隔离性。并发控制就是要用正确的方式调度并发 *** 作,使一个用户事务的执行不受其它事务的干扰,从而避免造成数据的不一致性。

并发一致性问题的解决办法

封锁(Locking)

封锁是实现并发控制的一个非常重要的技术。所谓封锁就是事务T在对某个数据对象例如表

REPEATABLE READ

锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。

也就是说你在同一事务中在不同时间读取同一条记录时,每次读的应该是一样的

不会被别的语句修改,但其他语句还可以insert

SERIALIZABLE

在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

也就是说在你所定的范围内,别人什么都干不了,包括insert


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/6913166.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-30
下一篇2023-03-30

发表评论

登录后才能评论

评论列表(0条)

    保存