For each row,ORA_ROWSCN returns the conservative upper bound system change number (SCN) of the most recent change to the row. This pseudocolumn is useful for determining approximately when a row was last updated. It is not absolutely precise, because Oracle tracks SCNs by transaction committed for the block in which the row resides. You can obtain a more fine-grained approximation of the SCN by creating your tables with row-level dependency tracking.
Please refer to CREATE TABLE ... NOROWDEPENDENCIES | ROWDEPENDENCIES for more information on row-level dependency tracking.
You cannot use this pseudocolumn in a query to a view. However, you can use it to refer to the underlying table when creating a view. You can also use this pseudocolumn in the WHERE clause of an UPDATE or DELETE statement.
ORA_ROWSCN is not supported for Flashback Query. Instead, use the version query pseudocolumns,
which are provided explicitly for Flashback Query.
Please refer to the SELECT ... flashback_query_clause for information on Flashback Query and
"Version Query Pseudocolumns" for additional information on those pseudocolumns.
简单说来就是默认情况,ora_rowscn记录的scn并不准确,记录的是block的scn;创建表的时候ROWDEPENDENCIES可以来使ora_rowscn真正记录行一级的scn;不能用在查询view时;不能用于flashback query。可以用来确认行所在块最后一次修改的scn;确认行所在块最后一次修改的大概时间;大部分的时候可以确定出两行记录创建的先后顺序(没在同一个块上);如果CREATE TABLE ... ROWDEPENDENCIES 可以精确到行。
乐观锁和ORA_ROWSCN
需要select ... for update做悲观锁定的时候,通过使用ORA_ROWSCN可以改成乐观锁定。一开始select数据的时候将ORA_ROWSCN查出来,修改后如果要写回数据库之前再比对下最新的ORA_ROWSCN就可以知道这期间数据是否有发生变化。
增量数据抽取和ORA_ROWSCN
每次抽取后记录最大的ORA_ROWSCN,下次抽取再基于上一次的SCN来获得最近修改过的数据即可。在10g之前,很多系统要实现增量数据抽取,要么通过解析日志,要么加触发器,要么就在表上加一个时间截字段。
ORA_ROWSCN其实就是第三种方式,只是这个字段由Oracle来维护,这样可以避免一些应用绕过时间截去更新其他字段带来的问题。不过,如果系统中使用了逻辑备库或者streams等逻辑复制的方案,而数据抽取又是基于逻辑备库的话,ORA_ROWSCN就可能对抽取后的数据分析有影响了,因为通过这个得到的时间是逻辑备库上记录变更的时间,而不是源库的时间了。
当然,如果纯粹只是做数据抽取,而不需要使用这个时间来做分析,还是问题不大的,但还是要考虑一旦逻辑备库出现故障需要重做的,则这个增量抽取要怎么来处理的问题。
测试
1、 基本测试,验证缺省情况Ora_rowscn只记录block级
SQL> create table rowscntest(id number,name varchar2(20));
Table created
SQL> insert into rowscntest values(1,'dave');
1 row inserted
SQL> insert into rowscntest values(1,'dave');
1 row inserted
SQL> commit;
Commit complete
SQL>
SQL> select dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
2 dbms_rowid.rowid_block_number(rowid) BLOCKNO,
3 dbms_rowid.rowid_row_number(rowid) ROWNO,
4 id,
5 name
6 from rowscntest;
REL_FNO BLOCKNO ROWNO ID NAME
---------- ---------- ---------- ---------- --------------------
8 222701 0 1 dave
8 222701 1 1 dave
SQL> select ora_rowscn,id from rowscntest;
ORA_ROWSCN ID
---------- ----------
155228124 1
155228124 1
SQL>
默认情况下,使用的是block header的SCN,所以这时候,如果我们改变该表的信息,block header 的scn 发生改变,那么对应block上所有的ora_rowscn 也会发生改变。
2、通过增加创建表的选项rowdependencies/norowdependencies,来对ora_rowscn测试
SQL> create table rowscntest2(id number,name varchar2(20)) rowdependencies;
Table created
启动行级别的跟踪。
SQL> insert into rowscntest2 values(1,'dave');
1 row inserted
SQL> insert into rowscntest2 values(2,'jack');
1 row inserted
SQL> commit;
Commit complete
SQL>
SQL> select dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
2 dbms_rowid.rowid_block_number(rowid) BLOCKNO,
3 dbms_rowid.rowid_row_number(rowid) ROWNO,
4 id,
5 name
6 from rowscntest2;
REL_FNO BLOCKNO ROWNO ID NAME
---------- ---------- ---------- ---------- --------------------
8 222709 0 1 dave
8 222709 1 2 jack
SQL> select ora_rowscn,id from rowscntest2;
ORA_ROWSCN ID
---------- ----------
155228359 1
155228359 2
2个ora_rowscn 是一样的。ora_rwscn 是在itl 发生cleanout 时刷到dscn的。 我们在进行一些事务操作查看一下。
SQL> update rowscntest2 set name='dave2' where id=1;
1 row updated
SQL> commit;
Commit complete
SQL> update rowscntest2 set name='jack2' where id=2;
1 row updated
SQL> commit;
Commit complete
SQL> select ora_rowscn,id from rowscntest2;
ORA_ROWSCN ID
---------- ----------
155228602 1
155228609 2
测试的ora_rowscn已经发生改变,我们再做一些改变
SQL> insert into rowscntest2 values(3,'john');
1 row inserted
SQL> commit;
Commit complete
SQL> insert into rowscntest2 values(4,'jerry');
1 row inserted
SQL> commit;
Commit complete
SQL> select ora_rowscn,id from rowscntest2;
ORA_ROWSCN ID
---------- ----------
155228602 1
155228609 2
155228815 3
155228820 4
3、最后执行一下与ORA_ROWSCN有关时间的测试
SQL> col SCN_TO_TIMESTAMP(ORA_ROWSCN) for a40
SQL> select scn_to_timestamp(ora_rowscn),id,name from rowscntest2;
SCN_TO_TIMESTAMP(ORA_ROWSCN) ID NAME
---------------------------------------- ---------- --------------------
29-11月-11 03.05.01.000000000 下午 1 dave2
29-11月-11 03.05.16.000000000 下午 2 jack2
29-11月-11 03.10.13.000000000 下午 3 john
29-11月-11 03.10.25.000000000 下午 4 jerry
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9399028/viewspace-712353/ ,如需转载,请注明出处,否则将追究法律责任。