5

私は、1 つの DB ですべての変更を取得し、それらを別の DB に同期するシンクロナイザー ソフトウェアを作成しています。Tこの目的のために、テーブルに2 つの列を追加しました。

alter table T add LastUpdate rowversion, LastSync binary(8) not null default 0

これで、最後の同期以降に変更されたすべての行を簡単に選択できます。

select * from T where LastUpdate > LastSync

ただし、同期を実行した後、2 つのフィールドを等しくする必要があります。ただし、行を更新するとタイムスタンプも更新されるため、次のようにする必要があります。

update T set LastSync=@@DBTS+1 where ID=@syncedId

しかし、私は疑問に思っています-これは常に機能しますか? の値を読み取った@@DBTS後、自分の行がコミットされる前に別のユーザーがどこかで行を挿入/更新した場合はどうなりますか? これは危険なコードですか?はいの場合、どうすれば改善できますか?

4

2 に答える 2

4

「LastSync」を実際のデータと同じテーブルに格納することは、まったくお勧めできません。行バージョンを持たない別のテーブルに格納してみてください。そうすれば、「行を更新するとタイムスタンプも更新される」という問題を回避できます。

シンクロナイザー ソフトウェアは、次のように動作します。

  • 追加テーブルから @LastSync 値を取得する
  • 「LastUpdate > @LastSync の T から @ThisSync = max(LastUpdate) を選択」
  • "Select * from T where LastUpdate > @LastSync and LastUpdate <= @ThisSync" は同期対象の行です
  • @ThisSync を新しい「LastSync」として追加テーブルに保存します。

同期の実行中に変更されたエントリは、max() クエリよりも高い rowversion 値を持ちます。次にシンクロナイザーが呼び出されたときに同期されます。

于 2010-10-22T11:45:45.400 に答える
-1

これをSerializableトランザクションで実行すると、他の読み取り/書き込みはこれらのテーブルに影響を与えることができなくなります。

RepeateableRead仕事もするかもしれません...

于 2010-10-22T11:03:37.720 に答える