丢失更新
丢失更新(lost update)是一个经典的数据库问题。实际上,所有多用户计算机环境都存在这个问题。
简单地说,出现下面的情况时(按以下所列的顺序),就会发生丢失更新。
(1)会话session1的一个事务获取(查询)一行数据,放入本地内存,显示给用户User1
(2)会话session2另一个事务也获取这一行,但显示给User2
(3)User1使用应用修改了这个一行并提交。session1的事务已经执行
(4)User2也修改这行并提交。session2的事务也执行。
这个过程称为“丢失更新”,因为第(3)步所做的所有修改都会丢失。
解决这个问题,Oracle有2种解决方案
1)悲观锁定
用户在屏幕上修改值之前,这个锁定方法就要起作用。例如,用户一旦有意对他选择的某个特定的行(屏幕可见)
执行更新,如单击一个按钮,就会放上一个行锁。那这个行锁就会持续到用户修改并提交。
select empno,ename,sal from emp where deptno = 10;
EMPNO ENAME SAL
----- ----- ----
7782 CLARK 2450
7839 KING 5000
7934 MILLER 1300
用户想更新MILLER行。在这个时间点上(即用户还没有在屏幕做任何修改,但这行已经从数据库中读出一段时间了),
应用会绑定用户选择的值,从而查询数据库,并确保数据尚未修改。可以使用一下命令模拟
variable empno number
variable ename varchar2(20)
variable sal number
exec :empno := 7934; :ename := 'MILLER'; :sal := 1300;
下面,除了简单查询值并验证数据尚未修改外,我们用使用FOR UPDATE NOWAIT 锁定这一行。
SELECT EMPNO,ENAME,SAL FROM EMP WHERE EMPNO = :EMPNO AND DECODE(ENAME,:ENAME,1) = 1
AND DECODE(SAL,:SAL,1) = 1 FOR UPDATE NOWAIT.
从而不允许其他会话更新。因此,这种方法称为悲观锁定(pessimistic locking)。
如果底层数据没有改变,就会再次得到MILLER行,而且这一行会被锁定,不允许其他会话更新(但是允许其他会话读)。
如果另一个用户正在更新这一行,我们就会得到一个ORA-00054:resource busy错误。相应地,必须等待更新这一行
的用户执行工作。
在选择数据和指定有意更新之间,如果有人已经修改这一行,我们就会得到0行。这说明,屏幕上的数据是过时的。为了避免
前面所述的丢失更新情况,应用需要重新查询,并在允许在最终用户修改之前锁定数据。
一旦成功地锁定了这一行,应用就会绑定新值,发出命令后执行修改:
UPDATE EMP SET ENAME = :ENAME,SAL = :SAL WHERE EMPNO = :EMPNO;
2)乐观锁定
第二种方法称为乐观锁定,即把所有锁定都延迟到即将执行更新之前才做。换句话说,我们会修改屏幕上的信息而不要锁。
我们很乐观,认为数据不会被其他用户修改。因此,等到最后一刻才知道我们的想法正确与否。
乐观控制的方法有很多种,主要介绍2种方法:
1、使用一个特殊的列,并且这个列由数据库的一个触发器或者应用程序代码来维护,可以告诉我们记录存储现行的版本号。
2、通过原来的数据计算校验和或散列值。
乐观锁定还是悲观锁定
那么哪种方法最好呢?根据我的经验,悲观锁定在Oracle中工作得非常好(但在ita数据库当中可能不是这样),而且与乐观
锁定相比,悲观锁定有很多优点。不过,它需要与数据库有一条有状态的连接,如客户/服务器连接,因为无法跨越连接持有锁。
所以在当前的许多情况下,悲观锁定不太现实。过去的应用可能只有数十个或上百个用户,对于这些应用,悲观锁定是我们的不二
选择。不过对现今大多数应用来说,一般都采用乐观并发控制。
在这些可用的方法中,我使用哪一种呢?推荐使用版本列方法,并增加一个时间戳列。从长远看,这样能为我们提供一个额外
的信息。而且与散列和检验和方法相比,计算的代价不是很昂贵,在处理LONG,LONG RAW,CLOB,BLOB和其他非常大的列时,散列或
检验和方法可能会遇到一些问题,而版本列方法则没有这些问题。
相关推荐
NULL 博文链接:https://364232252.iteye.com/blog/2368928
NULL 博文链接:https://sunfish.iteye.com/blog/1517230
如果两个事务同时执行,则其中一个的修改可能会丢失,因为第二个写入的内容并没有包括第一个事务的修改,这种模式发生在各种不同的情况下:增加计数器或更新账户余额(需要
是模拟SQL并行更新时数据丢失的实例,那位有好的解决办法,可以探讨一下。
◆丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 ◆脏读 A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复...
丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏读 A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,...
丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏读 A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据...
会出现数据不一致的现象,是丢失更新。对数据A需要上X锁,具体如下 T1 T2 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 XLOCK A READ A=18 A = A + 10 UPDATE A = 28 UNLOCLK X XLOCK A WAIT WAIT WAIT WAIT WAIT...
1.数据库的一大特点是数据共享,即用户可以并发访问数据库对象,但并发操作可能会引起丢失更新、不可重复读、读脏数据这几类数据不一致性的问题,于是就要进行并发控制。并发控制的主要技术是封锁,封锁对象的规模...
丢失更新 II.不可重复读 III.读脏数据 (4分)A 仅I和II B 仅I和III C 数据库原理全文共9页,当前为第2页。数据库原理全文共9页,当前为第2页。 仅II和III 数据库原理全文共9页,当前为第2页。 数据库原理全文共9...
5、云图存储与分享,图纸安全不丢失 更新内容: 1、新增文字批注 2、新增引线批注 3、新增直线批注 4、新增箭头批注 5、新增矩形批注 6、新增椭圆批注 7、新增手绘线批注 8、新增云线批注 9、新增限免功能 10、...
C、权限控制 D、丢失更新 5.当前应用最广泛的数据模型是( B)。 A、ER模型 B、关系模型 C、网状模型 D、层次模型 6.现有一个关系:借阅(书号、书名,库存数,读者号,借期,还期),假如同一本书允许一个读者多...
运行文件夹内卸载.bat和绿化.bat即可解决文件对视问题,有介意请不要下载,操作简单两个文件需要使用管理员运行
一键备份数据,客户信息,公司信息永不丢失 更新记录: 1、更新手机登陆绑定 2、新增从excel文件导入到电话本功能 3、新增用户信息导入电话本功能. 4、更新**志图片溢出问题 5、更新登录页面样式 6、增加...
什么是锁? 锁定问题 丢失更新 悲观锁定 乐观锁定 乐观锁定还是悲观锁定? 阻塞 死锁 锁升级
一键备份数据,客户信息,公司信息永不丢失 更新记录: 1、更新手机登陆绑定 2、新增从excel文件导入到电话本功能 3、新增用户信息导入电话本功能. 4、更新日志图片溢出问题 5、更新登录页面样式 6、增加首页本周...
21.1.5 第二类丢失更新 21.2 数据库系统的锁的基本原理 21.2.1 锁的多粒度性及自动锁升级 21.2.2 锁的类型和兼容性 21.2.3 死锁及其防止办法 21.3 数据库的事务隔离级别 21.3.1 在mysql.exe程序中设置...
21.1.5 第二类丢失更新 21.2 数据库系统的锁的基本原理 21.2.1 锁的多粒度性及自动锁升级 21.2.2 锁的类型和兼容性 21.2.3 死锁及其防止办法 21.3 数据库的事务隔离级别 21.3.1 在mysql.exe程序中设置...
21.1.5 第二类丢失更新 21.2 数据库系统的锁的基本原理 21.2.1 锁的多粒度性及自动锁升级 21.2.2 锁的类型和兼容性 21.2.3 死锁及其防止办法 21.3 数据库的事务隔离级别 21.3.1 在mysql.exe程序中设置...