19

Oracle にはSQL ServerRowVersionと同様のデータ型がありますか?

行を挿入または更新すると、対応する Version 列 (タイプはRowVersion) が自動的に更新されます。

MSDN は RowVersion について次のように述べています

  • データベース内で自動的に生成された一意の 2 進数を公開するデータ型です。通常、rowversion はテーブル行にバージョン スタンプを付けるメカニズムとして使用されます。ストレージサイズは 8 バイトです。rowversion データ型は単に増加する数値であり、日付や時刻は保持されません。

  • 各データベースには、データベース内の rowversion 列を含むテーブルに対して実行される挿入操作または更新操作ごとにインクリメントされるカウンターがあります。このカウンターは、データベースの行バージョンです。これは、クロックに関連付けることができる実際の時間ではなく、データベース内の相対時間を追跡します。テーブルには、rowversion 列を 1 つだけ含めることができます。rowversion 列を含む行が変更または挿入されるたびに、増分されたデータベースの rowversion 値が rowversion 列に挿入されます。

  • 行の rowversion 列を使用すると、行が最後に読み取られてから変更された値があるかどうかを簡単に判断できます。行が変更されると、rowversion 値が更新されます。行が変更されていない場合、rowversion 値は以前に読み取られたときと同じです。

  • 複数のユーザーが同時に行を更新しているときにデータベースの整合性を維持するために、テーブルに rowversion 列を追加できます。また、テーブルを再クエリせずに更新された行の数と行を知りたい場合もあります。

Oracle を使用してデータ モデルを設計しており、Version 列を使用して同時実行性を管理したいと考えています。

また、オラクルの世界でより良い方法があるかどうかも知りたいです。

4

3 に答える 3

17

Oracle には SCN (システム変更番号) があります: http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039

システム変更番号(SCN)は、Oracle Databaseで使用される論理的な内部タイム・スタンプです。SCN は、データベース内で発生するイベントを順序付けます。これは、トランザクションの ACID プロパティを満たすために必要です。Oracle DatabaseはSCNを使用して、すべての変更がディスク上にあると認識される前にSCNをマークして、リカバリで不要なREDOの適用を回避できるようにします。また、データベースは SCN を使用して、一連のデータに対して REDO が存在しないポイントをマークし、リカバリを停止できるようにします。

SCN は、単調に増加するシーケンスで発生します。観測されたSCNは論理的な時点を示し、観測が繰り返されると同等またはそれ以上の値が返されるため、Oracle DatabaseではSCNを時計のように使用できます。あるイベントの SCN が別のイベントよりも低い場合、そのイベントはデータベースよりも早い時期に発生しています。複数のイベントが同じ SCN を共有する場合があります。これは、データベースに関して同時に発生したことを意味します。

すべてのトランザクションには SCN があります。たとえば、トランザクションが行を更新する場合、データベースはこの更新が発生した SCN を記録します。このトランザクションの他の変更には、同じ SCN があります。トランザクションがコミットされると、データベースはこのコミットの SCN を記録します。


行の現在のSCNを調べるには、ORA_ROWSCN疑似列を使用します :
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
(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 がわかっている場合は、フラッシュバック クエリを使用して行の過去の値を取得でき
ます

。 :

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                               
于 2013-12-10T07:34:14.697 に答える