"チェックアウト"されたオブジェクトを追跡するテーブルがありますが、オブジェクトはさまざまな他のテーブルに存在します。目的は、特定のオブジェクトを1回のみチェックアウトできるように(つまり、2人のユーザーが同じオブジェクトをチェックアウトできないように)、基準に一致するオブジェクトをチェックアウトできるようにすることです。場合によっては、単一のオブジェクトが複数の表にまたがることがあり、すべてのユーザーの基準(問題の場合)を確認するために結合を使用する必要があります。SQLでの結合による原子的更新
は、ここで(うまくいけば、あなたがスキーマを推測することができます)非常に単純なクエリの例です:
update top (1) Tracker
set IsCheckedOut = 1
from Tracker t
join Object o on t.ObjectId = o.Id
join Property p on p.ObjectId = o.Id
where t.IsCheckedOut = 0
and o.SomePropertyColumn = 'blah'
and p.SomeOtherPropertyColumn = 42
によりfrom
サブクエリに、私はこのクエリはアトミックではないと思われるので、2人のユーザーがオブジェクトの同じ味を要求します同時に、同じオブジェクトをチェックアウトすることができます。
本当ですか?もしそうなら、私はこれをどのように修正するのですか?
output DELETED.*
句を追加し、IsCheckedOut
列の戻り値が1の場合、ユーザーがクエリを再試行すると考えましたが、これは正しく動作すると思います。ユーザーが再試行を心配する必要がないようなものを得るのが好きです。完全な説明については
EDIT
は、以下のSqlZimの回答を参照してください、私はちょうど上に掲載クエリに直接ヒントを追加することができ、この単純なケースのために:
update top (1) Tracker
set IsCheckedOut = 1
from Tracker t (updlock, rowlock, readpast)
join Object o on t.ObjectId = o.Id
join Property p on p.ObjectId = o.Id
where t.IsCheckedOut = 0
and o.SomePropertyColumn = 'blah'
and p.SomeOtherPropertyColumn = 42
マインドは、与えられた例をもう少し詳しく説明していますか?それが正しいと判明すれば、私はそれを答えとして受け入れます。 – gzak