Oracle事务隔离
我有一个SaveApp()方法,它将停用现有记录并插入一个新记录.
void SaveApp(int appID) { begin transaction; update; insert; commit transaction; } 假设在数据库表SalesApp中,我有2条appID等于123的记录; >记录1,appID 123,不活动 如果我同时在两个线程中调用此方法SaveApp(),第一个事务(让我们称之为T1)将更新现有的两个记录,而第二个事务(让我们称之为T2)等待. T1完成后,此表中将有三条记录.但是,不知何故T2不知道新插入的记录,T2中的更新查询只更新前两个记录,并插入第四个记录. 在这两个方法调用之后,在数据库中,我们现在将有4条记录,第3条和第4条都是活动的,这是错误的. >记录1,不活动 你知道任何解决方案都可以解决这个问题吗?我尝试使用隔离级别序列化,但不起作用. 谢谢! 您是否有另一个表,每个AppId占一行,通过唯一或主键约束强制执行?如果是这样,请在父表上使用select for update来序列化每个AppId的访问权限.创建表: 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.并且不会继续. 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对此问题的答案,以获得一个约束,该约束强制执行A??ppId只能有一个活动记录的规则.因此,最终解决方案将包含两个部分,即如何以获得所需内容的方式进行更新的答案,以及Patrick确保表符合保护数据完整性的要求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |