Oracle 有 SCN(系统更改编号):http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039 http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039
系统更改号 (SCN) 是 Oracle 数据库使用的逻辑内部时间戳。 SCN 对数据库内发生的事件进行排序,这是满足事务的 ACID 属性所必需的。 Oracle 数据库使用 SCN 来标记在该 SCN 之前所有更改都位于磁盘上的 SCN,以便恢复时避免应用不必要的重做。数据库还使用 SCN 来标记一组数据不存在重做的点,以便停止恢复。
SCN 以单调递增的顺序出现。 Oracle 数据库可以像时钟一样使用 SCN,因为观察到的 SCN 指示逻辑时间点,并且重复观察会返回相等或更大的值。如果一个事件的 SCN 低于另一事件,则该事件相对于数据库发生的时间更早。多个事件可能共享相同的 SCN,这意味着它们相对于数据库同时发生。
每笔交易都有一个SCN。例如,如果事务更新一行,则数据库会记录发生此更新的 SCN。此事务中的其他修改具有相同的 SCN。当事务提交时,数据库会记录本次提交的 SCN。
使用 ORA_ROWSCN 伪列检查行的当前 SCN:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145 http://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145
一个例子:
SELECT ora_rowscn, t.* From test t;
演示 -->http://www.sqlfiddle.com/#!4/535bc/1 http://www.sqlfiddle.com/#!4/535bc/1
(在 SQLFiddle 上,显式提交显然不起作用 - 在真实数据库上,每次提交都会增加 SCN)。
“真实”数据库的示例:
CREATE TABLE test(
id int,
value int
);
INSERT INTO test VALUES(1,0);
COMMIT;
SELECT ora_rowscn, t.* FROM test t;
ORA_ROWSCN ID VALUE
---------- ---------- ----------
3160728 1 0
UPDATE test SET value = value + 1 WHERE id = 1;
COMMIT;
SELECT ora_rowscn, t.* FROM test t;
ORA_ROWSCN ID VALUE
---------- ---------- ----------
3161657 1 1
UPDATE test SET value = value + 1 WHERE id = 1;
COMMIT;
SELECT ora_rowscn, t.* FROM test t;
ORA_ROWSCN ID VALUE
---------- ---------- ----------
3161695 1 2
如果事务的 SCN 已知,我们可以使用闪回查询来获取该行的过去值:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#g1026131 http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#g1026131
一个例子:
SELECT t.*,
versions_startscn, versions_starttime,
versions_endscn, versions_endtime,
versions_xid, versions_operation
FROM test VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE t;
ID VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID VERSIONS_OPERATION
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------
1 2 3161695 13/12/10 08:19:39 06000300EA070000 U
1 1 3161657 13/12/10 08:18:39 3161695 13/12/10 08:19:39 06001200EA070000 U
1 0 3161657 13/12/10 08:18:39
SELECT t.*,
versions_startscn, versions_starttime,
versions_endscn, versions_endtime,
versions_xid, versions_operation
FROM test VERSIONS BETWEEN SCN 3161657 AND 3161657 t;
ID VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID VERSIONS_OPERATION
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------
1 1 3161657 13/12/10 08:18:39 06001200EA070000 U