oracle 在事务里 查询,Oracle 事务里面的查询 for update

我是一名.net 开发人员,在.net 处理Oracle 数据库事务的时候有些经验需要分享还是并发引起的,因为在本人的系统中,有一些错误数据始终分析不出来原因,也无法复现,长时间的日志追踪中发现原来是 并发操作引起的错误数据。

再归根结底就是因为 A 事务 先 select 再 更新,B事务 也是 先Select 再更新。但是我原先程序中的 select 并没有使用 for update,虽然这一连串的操作都在 BeginTransaction 之中,但是没有避免到并发操作引起的问题。

nowait找到问题原因就好解决了,我们可以在select的时候 加上  for update,或者 for update nowait

其中nowait是可选项。

此子句的意思就像他的字面意思,也就是说现在执行的select操作是为了本事务中的后续的update服务的。这时候系统会试图锁定查询出来的记录,不 允许其他事务修改它们。如果指定了nowait,则系统如果无法锁定记录,就会直接报错,并不会等待其他占有资源的事务释放资源。我这有一些我做的测试结 果

事务A:Select * From Test_A Where ID = ’01’ For Update NoWait;

事务B:Select * From Test_A Where ID = ’01 ’ For Update ;

事务C:Update Test_A Set Name = ’Test_01’ Where ID = ‘01’ ;

执行顺序 执行结果

首先 然后 执行结果

---- ---- ----

事务A 事务A 系统报错:ORA-00054: 资源正忙,要求指定 NOWAIT

事务A 事务B 事务B挂起,等待事务A释放资源

事务A 事务C 事务C挂起,等待事务A释放资源

事务B 事务A 系统报错:ORA-00054: 资源正忙,要求指定 NOWAIT

事务B 事务B 事务B挂起,等待事务A释放资源。(原文有问题,应该是等待前一个事务B释放资源)

事务B 事务C 事务C挂起,等待事务B释放资源

事务C 事务A 系统报错:ORA-00054: 资源正忙,要求指定NOWAIT

事务C 事务B 事务B挂起,等待事务C释放资源

不过在OEM中的PL SQL WORKSHEET中执行的话,如果执行倒数第2个实验,执行第2个事务A只有执行超过3次后,OEM才会报错,前几次OEM好象是忽略此操作。

--------------------------------------------------------------------------------------------------------------

在多数情况下,提取循环中所完成的处理都会修改由游标检查出的行,PL/SQL提供了进行这样处理的一种语法。

这种语法包括两部分——在游标声明部分的FOR UPDATE子句和在UPDATE或DELETE语句中的WHERE CURRENT OF 子句。

通常,SELECT操作将不会对正处理的行执行任何锁定设置,这使得连接到该数据库的其他会话可以改变正在选择的数据。

但 是,结果集仍然是一致性的。当确定了活动集以后,在执行OPEN的时刻,ORACLE会截取下该表的一个快照。在此时刻以前所提交的任何更改操作都会在活 动集中反映出来。在此时刻以后所进行的任何更改操作,即使已经提交了它们,都不会被反映出来,除非将该游标重新打开。但是使用FOR UPDATE子句, 在OPEN返回以前的活动集的相应行上会加上互斥锁,这些锁会避免其他的会话对活动集中的行进行更改。直到整个事务被提交为止。

示例:

DECLARE

CURSOR C_CUR IS SELECT * FROM STUDENDS FOR UPDATE OF XM;

BEGIN

OPEN C_CUR;

WHILE C_CUR%FOUND LOOP

UPDATE STUDENDS SET XM='AA'||XM WHERE CURRENT OF C_CUR;

END LOOP;

CLOSE C_CUR;

COMMIT;

END; 需要注意的是:1、UPDATE语句仅更新在游标声明的FOR UPDATE子句处列出的列。如果没有列出任何列,那么所有的列都可以更新。 2、示例中的COMMIT是在提取循环完成以后才完成的,因为COMMIT将释放由该会话持有的所有锁。因为FOR UPDATE子句获得了锁,所以COMMIT将释放这些锁。当锁释放了,该游标就无效了。所以后继的提取操作都将返回ORACLE错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值