set echo on
drop table t;
create table t ( x int primary key, name varchar2(30) ) rowdependencies;
insert into t values ( 1, 'john' );
insert into t values ( 2, 'mary' );
commit;
variable ora_rowscn number
set autoprint on
exec select ora_rowscn into :ora_rowscn from t where x = 2;
set echo off
prompt in another session issue:
prompt variable ora_rowscn number
prompt set autoprint on
prompt exec select ora_rowscn into :ora_rowscn from t where x = 2;;
prompt and come back here and hit enter...
pause
set echo on
update t set name = 'beth' where x = 2 and ora_rowscn = :ora_rowscn;
set echo off
prompt in another session issue:
prompt update t set name = 'sally' where x = 2 and ora_rowscn = :ora_rowscn;;
prompt and come back here and hit enter...
pause
commit;
set echo off
prompt now commit in the other session and notice your lost update :(
create table t ( x int primary key, name varchar2(30), version_Number number);
create sequence s_t start with 1 increment by 1;
insert into t values ( 1, 'john', s_t.nextval);
insert into t values ( 2, 'mary', s_t.nextval);
commit;
select * from t;
你会看到这样的东西:
X NAME Version_Number
1 john 1
2 mary 2
.
-- first session
update t set name = 'beth', version_number = s_t.nextval where x = 2 and version_number = 2;
-- second session
update t set name = 'sally', version_number = s_t.nextval where x = 2 and version_number = 2;
-- First session
commit;
-- Second session returns with no updated records...
通常我认为系统在读取数据时会选择 ora_rowscn 值,而在写回数据时会将该值指定为更新语句的一部分。如果没有行更新,则记录已被删除或记录已更改。
las,ora_rowscn 方法不会很好地工作。它仍然启用“丢失的更新”。
我有来自 AskTom 的信息:ORA_ROWSCN for optimistic locking
在此处复制示例以预测死链接...
恕我直言,您应该做的是在您的表中添加一个额外的列(例如:Version_Number),您可以在其中设置更新记录时序列的 nextval(使用触发器,或在包代码中执行此操作)。
WorkFlow: Client 查询一些行并获取带有version_Number 的数据。更新此数据时,他需要检查 version_number 与记录中的当前 version_number。如果它们不同,则不会更新任何行,您应该向客户端返回一个错误 (No_Records_Found)。
你会看到这样的东西:
.
正如我所说,您应该通知客户没有更新记录,但这可能有两个原因:
在这两种情况下,客户端都必须再次刷新此记录并确定下一步要做什么。