2017-08-09 11 views
1

私たちは、顧客データの現在のバージョンを示す単調に増加するキーを保持するユースケースを持っています。これは、システムで使用され、最新のバージョンを把握し、データの読み取りと処理の間に遅延があり、複数のバージョンを取得した場合、サードパーティの発信者の競合を解決します。自己管理単調増加キーまたはORシステムのタイムスタンプ

CUSTOMER_RESOURCE_ID CURRENT_VERSION 
132323     1234 

何かがこのリソースのために変更された場合、我々は(我々がいる限り、それがダウンしていないとして1300年にそれを増やしても、全く問題あり)1234年から1235年にバージョンをインクリメントします。そのためには、まず値を読み込んで更新する必要があります。

その他の方法として、DBのタイムスタンプを使用して、常に増加するDBタイムスタンプでバージョンを更新することができます。これは単なるシステムなので、DBを変更するときにクロックスキューが発生する可能性があります。また、一度に1つのスレッドのみがリソースを更新する別のロックがあるので、複数のスレッドがある時間内にデータを更新する場合(つまり、タイムスタンプの粒度が最小である場合)には心配していません。

データベースのシステムタイムスタンプを使用して、ちょうど更新で選択と増分を避けることができるのだろうかと思っていました。

この方法に問題はありますか?データベースのオーバーヘッドが少なくなると思っていますが、ここでどれくらい節約できるか分かりません。

+2

あなたは一例で説明できますか? –

+1

システムクロックの細かさによっては、おそらく複数のスレッド間の一意性を保証できません。 –

+0

ありがとうございます、アップデートをご覧ください。 – instanceOfObject

答えて

0

多くのアプローチについて説明します。私の考えでは;

- データベースのタイムスタンプではなく、デフォルトの列の値でさえもインクリメンタルスケープを使用できます。多分、ミリ秒はあなたのために問題を引き起こす可能性があります。あなたのテーブルではない非常に大きいですし、あなたのリソースが十分にある場合は

--inさらに、あなたは(すなわち。select * from customers where customer_id = 123 and is_last_version= 1 --toもパフォーマンスでお客さまの最後のバージョンを照会するために、すべての挿入と更新しますis_last_version列を追加することができます注文のコストを取り除く)。したがって、どの行が最後のバージョンであるかを知ることができます。しかし、それぞれの挿入時間は長くなります。それをテストする必要があります。

例:

CUSTOMER_RESOURCE:

CUSTOMER_RESOURCE_ID CURRENT_VERSION_ID   IS_LAST_VERSION   INSERT_TIME 
         (default seq)        (default sysdate --optionally) 
132323      1       1    
132324      2       1 
132325      3       1      
132326      4       0 
132327      5       0 
132328      6       1 
132326      7       0 
132329      8       1 
132326      9       1 
132327      10       1 

挿入:

update CUSTOMER_RESOURCE 
SET IS_LAST_VERSION = 0 
where CUSTOMER_RESOURCE_ID = 132326; 

insert into CUSTOMER_RESOURCE(CUSTOMER_RESOURCE_ID,IS_LAST_VERSION) VALUES (132326,1); 
COMMIT; 

顧客の選択最終バージョン:

select * from customers where customer_id = 123 and is_last_version= 1; 
関連する問題