void SaveApp(int appID) { begin transaction; update; insert; commit transaction; }
假设在数据库表SalesApp中,我有2条appID等于123的记录;
>记录1,appID 123,不活动
>记录2,活跃
如果我同时在两个线程中调用此方法SaveApp(),第一个事务(让我们称之为T1)将更新现有的两个记录,而第二个事务(让我们称之为T2)等待.
T1完成后,此表中将有三条记录.但是,不知何故T2不知道新插入的记录,T2中的更新查询只更新前两个记录,并插入第四个记录.
在这两个方法调用之后,在数据库中,我们现在将有4条记录,第3条和第4条都是活动的,这是错误的.
>记录1,不活动
>记录3,活跃
>记录4,活跃
你知道任何解决方案都可以解决这个问题吗?我尝试使用隔离级别序列化,但不起作用.
谢谢!
创建表:
session_1> create table parent (AppId number primary key); Table created. session_1> create table child (AppId number not null references Parent(AppId) 2,status varchar2(1) not null check (status in ('A','I')) 3,InsertedAt date not null) 4 / Table created.
插入起始值:
session_1> insert into Parent values (123); 1 row created. session_1> insert into child values (123,'I',sysdate); 1 row created. session_1> insert into child values (123,'A',sysdate); 1 row created. session_1> commit; Commit complete.
开始第一笔交易:
session_1> select AppId from Parent where AppId = 123 for update; APPID ---------- 123 session_1> update Child set Status = 'I' where AppId = 123 and Status = 'A'; 1 row updated. session_1> insert into child values (123,sysdate); 1 row created.
在提交之前,在第二个会话中,确保我们只看到第一行:
session_2> select * from Child; APPID S INSERTEDAT ---------- - ------------------- 123 I 2010-08-16 18:07:17 123 A 2010-08-16 18:07:23
开始第二笔交易:
session_2> select AppId from Parent where AppId = 123 for update;
会话2现在被阻止,等待会话1.并且不会继续.
提交会话1将取消阻止会话
session_1> commit; Commit complete.
第2节我们现在看到:
APPID ---------- 123
完成第二笔交易:
session_2> update Child set Status = 'I' where AppId = 123 and Status = 'A'; 1 row updated. session_2> insert into child values (123,sysdate); 1 row created. session_2> commit; Commit complete. session_2> select * from Child; APPID S INSERTEDAT ---------- - ------------------- 123 I 2010-08-16 18:07:17 123 I 2010-08-16 18:07:23 123 I 2010-08-16 18:08:08 123 A 2010-08-16 18:13:51
编辑技术来自Thomas Kyte的专家Oracle数据库架构第二版,第23-24页. http://www.amazon.com/Expert-Oracle-Database-Architecture-Programming/dp/1430229462/ref=sr_1_2?ie=UTF8&s=books&qid=1282061675&sr=8-2
编辑2我还建议实施Patrick Merchand对此问题的答案,以获得一个约束,该约束强制执行AppId只能有一个活动记录的规则.因此,最终解决方案将包含两个部分,即如何以获得所需内容的方式进行更新的答案,以及Patrick确保表符合保护数据完整性的要求.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。