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

数据库的并发 *** 作可能带来哪些问题 丢失更新 死锁 违反唯一性约束,第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在对某个数据对象例如表

当多个用户对同一数据进行 *** 作时,就需要对该 *** 作进行并发状态下的事务控制,如不进行事务控制会产生丢失更新、脏读、非重复读、幻读等问题。

1.丢失更新丢失更新是指多个事务同时 *** 作一行数据时,并且基于最初选定的值被更改时,每个事务都不知道其他事务的存在,最后的更新将重写由其他事务所做的更新,这将导致数据丢失现象的发生。

2.脏读脏读是指当第二个事务选择其他事务正在更新时,会发生未确认的相关性问题,第二个事务正在读取的数据还没有确认并且可能被更新此行的事务所更改。

3.非重复读非重复读和脏读类似,是指第二个事务多次访问同一行数据而且每次读取不同数据时,会发生不一致的问题。

4.幻读幻读是指当某个事务对某表的全部记录执行删除或其他 *** 作时,而另外的其他事务正在往该表插入数据, *** 作完成后,前面的事务会发现还有记录存在。因像发生幻觉一样,故称为幻读。

编辑可能需要比较长的时间,

建议不锁定,而在每次更新数据库的时候,比较一下,如果和刚开始取出来的

不一样,则提示,或者打开新的副本;让选择;

可能需要增加一个字段保存最后更新时间

时间上可能受不了!系统时间要求很高

并发问题

如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括:

丢失或覆盖更新。

未确认的相关性(脏读)。

不一致的分析(非重复读)。

幻像读。

丢失更新

当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。

例如,两个编辑人员制作了同一文档的电子复本。每个编辑人员独立地更改其复本,然后保存更改后的复本,这样就覆盖了原始文档。最后保存其更改复本的编辑人员覆盖了第一个编辑人员所做的更改。如果在第一个编辑人员完成之后第二个编辑人员才能进行更改,则可以避免该问题。

未确认的相关性(脏读)

当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。

例如,一个编辑人员正在更改电子文档。在更改过程中,另一个编辑人员复制了该文档(该复本包含到目前为止所做的全部更改)并将其分发给预期的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所做的编辑并保存了文档。分发给用户的文档包含不再存在的编辑内容,并且这些编辑内容应认为从未存在过。如果在第一个编辑人员确定最终更改前任何人都不能读取更改的文档,则可以避免该问题。

不一致的分析(非重复读)

当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。

例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

幻像读

当对某行执行插入或删除 *** 作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入 *** 作,事务的第二次或后续读显示有一行已不存在于原始读中。

例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

从上面可以看到,解决并发主要是用到了锁和事务。

锁 :给记录或表加上锁是为了对当前 *** 作对象加上一个状态表示位,

让其它用户在获取编辑权限时有了判断。

事务:是为了保证一组 *** 作的完整性。

一般处理并发问题的做法:

1.开启事务

2.申请写权限,也就是给对象(表或记录)加锁.

3.如果失败,则结束事务,过一会重试。

4.如果成功,也就是给对象加锁成功,防止其它用户再用同样的方式打开。

5.进行编辑 *** 作

6.写入所进行的编辑结果

7.如果写入成功,则提交事务,完成 *** 作。

8.如果写入失败,则回滚事务,取消提交。

9.(7.8)两步 *** 作已释放了锁定的对象,恢复到 *** 作前的状态。


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存