oracle并发执行update,ORACLE并发性锁(for update)测试

FOR UPDATE释放条件

1.数据库连接中断

2.程序停止

3.COMMIT

4.ROLLBACK

1.select * from ls.lims_employees where empno='0001' for update

只有当前用户能查看SELECT记录,其他用户可以select * from ls.lims_employees where empno='0001'  查询,但要加for update则必须等待前一个用户提交才能查

2.SELECT FOR UPDATE SKIP LOCKED选项是ORACLE的一个未公开的特性,它的含义是SELECT时跳过被锁的记录。

考虑下面的例子:

会话1:

SQL> select * from sex_dict ;

SERIAL_NOS SEX_INPUT_CO

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

1 1男   N

9 0未知 WZ

2 2女   N

4 9未定 WD

SQL> select * from sex_dict where serial_no = 1 for update ;

SERIAL_NOS SEX_INPUT_CO

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

1 1男   N

会话2:

查询并锁住serial_no in (1,2)的记录

SQL> select * from sex_dict where serial_no in ( 1, 2) for update ;

此时会话2挂住,直到会话1事务结束。

加上”NOWAIT”选项

SQL> select * from sex_dict where serial_no in ( 1, 2) for update nowait ;

select * from sex_dict where serial_no in ( 1, 2) for update nowait

*

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

因为serial_no = 1的记录被会话锁住,所以这个操作没有成功。

加上SKIP LOCKED选项

SQL> select * from sex_dict where serial_no in ( 1, 2) for update nowait skip locked;

SERIAL_NOS SEX_INPUT_CO

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

2 2女   N

会话2只锁住serial_no=2的记录,跳过serial_no=1的记录。

这个特性适合例如消息队列的操作,当消息到达时,处理消息的各个客户选取并锁住一个消息处理,但不能阻塞其它客户处理消息。其它客户则处理没有被锁的消息。这个可以参考AnySQL.net的《在Oracle中如何跳过被别人锁住的记录?》

利用这个特点,Tomac给出了一个不跳号序列号的方法

===========================================

未加for update并发时,会出现超发情况。

declare

-- Local variables here

i integer;

begin

-- Test statements here

SELECT COL2 INTO I FROM PUSER.AAA WHERE COL1='A1'  ;

IF I>80 THEN

UPDATE PUSER.AAA SET COL2=COL2 - 80 WHERE COL1='A1';

END IF;

end;

declare

-- Local variables here

i integer;

begin

-- Test statements here

加行级锁,等待10秒

SELECT COL2 INTO I FROM PUSER.AAA WHERE COL1='A1'  for update wait 10;

IF I>80 THEN

UPDATE PUSER.AAA SET COL2=COL2 - 80 WHERE COL1='A1';

END IF;

end;

舉個例子: 假設商品表單 products 內有一個存放商品數量的 quantity ,在訂單成立之前必須先確定 quantity 商品數量是否足夠 (quantity>0) ,然後才把數量更新為 1。

不安全的做法:

SELECT quantity FROM products WHERE id=3; UPDATE products SET quantity = 1 WHERE id=3;

為什麼不安全呢? 少量的狀況下或許不會有問題,但是大量的資料存取「鐵定」會出問題。

如果我們需要在 quantity>0 的情況下才能扣庫存,假設程式在第一行 SELECT 讀到的 quantity 是 2 ,看起來數字沒有錯,但是當 MySQL 正準備要 UPDATE 的時候,可能已經有人把庫存扣成 0 了,但是程式卻渾然不知,將錯就錯的 UPDATE 下去了。

因此必須透過的交易機制來確保讀取及送交的資料都是正確的。

於是我們在 MySQL 就可以這樣測試: (註1)

SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE; =========================================== 此時 products 資料中 id=3 的資料被鎖住(註3),其它交易必須等待此次交易 送交後才能執行 SELECT * FROM products WHERE id=3 FOR UPDATE (註2) 如此可以確保 quantity 在別的交易讀到的數字是正確的。 =========================================== UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK; =========================================== 送交(Commit)寫入資料庫,products 解鎖。

舉個例子: 假設商品表單 products 內有一個存放商品數量的 quantity ,在訂單成立之前必須先確定 quantity 商品數量是否足夠 (quantity>0) ,然後才把數量更新為 1。

不安全的做法:

SELECT quantity FROM products WHERE id=3; UPDATE products SET quantity = 1 WHERE id=3;

為什麼不安全呢? 少量的狀況下或許不會有問題,但是大量的資料存取「鐵定」會出問題。

如果我們需要在 quantity>0 的情況下才能扣庫存,假設程式在第一行 SELECT 讀到的 quantity 是 2 ,看起來數字沒有錯,但是當 MySQL 正準備要 UPDATE 的時候,可能已經有人把庫存扣成 0 了,但是程式卻渾然不知,將錯就錯的 UPDATE 下去了。

因此必須透過的交易機制來確保讀取及送交的資料都是正確的。

於是我們在 MySQL 就可以這樣測試: (註1)

SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE; =========================================== 此時 products 資料中 id=3 的資料被鎖住(註3),其它交易必須等待此次交易 送交後才能執行 SELECT * FROM products WHERE id=3 FOR UPDATE (註2) 如此可以確保 quantity 在別的交易讀到的數字是正確的。 =========================================== UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK; =========================================== 送交(Commit)寫入資料庫,products 解鎖。

IAR下载Linux环境适配:入门级安装指导 详细介绍如何在Linux系统中完成iar下载与环境配置,帮助开发者快速上手IAR集成开发环境,解决常见安装问题,提升开发效率。 阅读详情

相关推荐

Oracle的行语法:FOR UPDATE

在上面的示例中,我们创建了一个名为"employees"的表,并插入了一些示例数据。然后,我们开始了一个事务,并使用SELECT语句查询了employee_id为1的行,并使用FOR UPDATE语法进行行级定。接下来,我们使用UPDATE语句修改了被定的行的salary字段的值,并最后提交了事务。在Oracle数据库中,使用FOR UPDATE语法可以对查询结果集中的行进行行级定。OracleFOR UPDATE语法可以用于对查询结果集中的行进行行级定,防止并发修改数据。

BjmmVue的博客 747

OracleforUpdate语句

Select...for update 语句是我们经常使用手工加语句。通常情况下,select语句是不会对数据加,妨碍影响其他的DML和DDL操作。同时,在多版本一致读机制的支持下,select语句也不会被其他类型语句所妨碍。 借助for update子句,我们可以在应用程序的层面手工实现数据加保护操作。 加范围子句: 在select ....for update 之后,可以使...

凡磊的技术栈 2万+

【精选毕业设计】基于WeiboSenti100k 数据集bert-base-chinese微调的中文情感分析任务源码+项目说明.zip

【精选毕业设计】基于WeiboSenti100k 数据集bert-base-chinese微调的中文情感分析任务源码+项目说明.zip

oracleupdate并发,关于update操作并发问题

在高并发的场景下,经常会遇到这种情况:A请求过来,查询出来一条数据,进行update操作,与此同时B请求也在这个时候过来,对这条数据进行查询,并进行操作。此时就会出现B在A之后进行查询操作,但是实际B的数据却被A覆盖。表名A,字段名为 number,如下的SQL语句:甲操作 语句1:select num from store where id='1';假设此时甲获取到 num= 99乙操作 语句2...

weixin_42398730的博客 4577

oraclefor update的用法是什么

update

bjgzxx的专栏 1845

Oracle-FOR UPDATE 使用

Oracle数据库中,FOR UPDATE是一个SQL子句,它通常与SELECT语句一起使用来定表中的行,这样其他事务就不能同时修改这些行,这有助于实现数据的一致性和隔离性;: 当你提交事务时,所有由该事务产生的都会被自动释放。: 当你回滚事务时,所有由该事务产生的也会被自动释放。: 如果事务没有显式提交或回滚,当你关闭数据库会话时,所有未提交的事务都会被自动回滚,因此也会被释放NOWAIT。

宁静致远 1411

ORACLE并发性(for update)测试

FOR UPDATE释放条件1.数据库连接中断2.程序停止3.COMMIT4.ROLLBACK 1.select * from ls.lims_employees where empno=0001 for update只有当前用户能查看SELECT记录,其他用户必须等待  2.SELECT FOR UPDATE SKIP LOCKED选项是ORACLE的一个未公开的特性,它

北极星的专栏 7266

一文带你完全理解在oraclefor updatefor update nowait的区别

首先一点,如果只是select 的话,Oracle是不会加任何的,也就是Oracle对 select 读到的数据不会有任何限制,虽然这时候有可能另外一个进程正在修改表中的数据,并且修改的结果可能影响到你目前select语句的结果,但是因为没有,所以select结果为当前时刻表中记录的状态。如果加入了for update, 则Oracle一旦发现(符合查询条件的)这批数据正在被修改,则不会发出该select语句查询,直到数据被修改结束(被commit),马上自动执行这个select语句。

程序员伊成 2329

oracle的delete会整个表吗,DML操作update和delete时产生的

本文主要是测试执行dml操作时都产生哪些测试了delete和update时产生的以及并发删除一个表时产生的测试环境Oracle102011、会话1 找到此会话的sidSQL> set time onset prompt s114:46:02 s1> select sid from v$mystat where rownum<=1;SID----------3242、...

weixin_36212560的博客 4872

oraclefor updatefor update of的区别

对比区别:   1 select * from TTable1 for update 定表的所有行,只能读不能写   2  select * from TTable1 where pkid = 1 for update定pkid=1的行   3  select *

一个人有了信仰,不管成不成功,至少不会迷茫。 1266

for updatefor update wait,for update nowait的区别

首先一点 在oracle中,如果只是select 的话,Oracle是不会加任何的,也就是Oracle对 select 读到的数据不会有任何限制,虽然这时候有可能另外一个进程正在修改表中的数据,并且修改的结果可能影响到你目前select语句的结果,但是因为没有,所以select结果为当前时刻表中记录的状态。 他们三个共同点: 当使用select for update 或select f...

知跬步,至千里 3946

如何在Django模型中管理并发性 orm select_for_update

为单用户服务的桌面系统的日子已经过去了 - 网络应用程序现在正在为数百万用户提供服务,许多用户出现了广泛的新问题 - 并发问题。 在本文中,我将介绍在Django模型中管理并发性的两种方法 问题 为了演示常见的并发问题,我们将使用银行账户模型: 开始我们为帐户实例提供一个简单的存款和撤销方法: 这似乎是足够简单的,甚至可能通过本地主机的单元测试和集成测试。 但...

平头哥(Adger)的博客 1069

oracle数据库 for update of和for update区别

对比区别:   select * from TTable1 for update 定表的所有行,只能读不能写   2  select * from TTable1 where pkid = 1 for update定pkid=1的行   3  select * from Table1 a join Table2 b on a.pkid=b.pkid for update 定两个表的所有记...

dhklsl的专栏 1618

mysql for update of_Oracle for update of 和 for update区别

Oracle for update of 和 for update区别select * from TTable1 for update 定表的所有行,只能读不能写2 select * from TTable1 where pkid = 1 for update定pkid=1的行3 select * from Table1 a join Table2 b on a.pkid=b.pkid...

weixin_33411250的博客 616

oracle for updatefor update nowait的区别

1、for updatefor update nowait 的区别: 首先一点,如果只是select 的话,Oracle是不会加任何

w36680130的博客 2102

数据库 oracle for update of 和 for update区别【经典】

对比区别:   select * from TTable1 for update 定表的所有行,只能读不能写   2  select * from TTable1 where pkid = 1 for update定pkid=1的行   3  select * from Table1 a join Table2 b on a.pkid=b.pkid for update 定两个表的...

iteye_2153的博客 909

oracle

一、表的处理 Oracle表比较简单,查询表的session杀掉就可以了。 1、以下几个为相关表 SELECT * FROM V$LOCK; SELECT * FROM V$SQLAREA; SELECT * FROM V$SESSION; SELECT * FROM V$PROCESS; SELECT * FROM V$LOCKED_OBJECT; SELECT * FROM ALL_OBJECTS; SELECT * FROM V$SESSION_WAIT; 2、查看

weixin_44767040的博客 2万+

讲解有关"SELECT FOR UPDATE"的一些概念

 在网上找了些文章,总结在了一起....statement: 一个SQL语句。  session: 一个由ORACLE用户产生的连接,一个用户可以产生多个SESSION ,但相互之间是独立的。 transaction:所有的改变都可以划分到transaction里,一个transaction包含一个或多个SQL。当一个SESSION建立的时候就是一个TRANSACTION开始的时刻

上海夜未眠 1251

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

我是一名.net 开发人员,在.net 处理Oracle 数据库事务的时候有些经验需要分享还是并发引起的,因为在本人的系统中,有一些错误数据始终分析不出来原因,也无法复现,长时间的日志追踪中发现原来是 并发操作引起的错误数据。再归根结底就是因为 A 事务 先 select 再 更新,B事务 也是 先Select 再更新。但是我原先程序中的 select 并没有使用 for update,虽然这一连...

weixin_33656211的博客 636

ORACLE 关于CURSOR中的FOR UPDATE关键字

ORACLE 关于CURSOR中的FOR UPDATE关键字

kinglino520的专栏 2377
上一篇: oracle基础使用,oracle基本操作
下一篇: oracle 数据插入全部列,如何将python列表插入到特定的Oracle数据库列中?
明天见日月
博客等级 码龄6年 22粉丝 76原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值