MongoDBなどのドキュメントデータベース(別名NoSQL)について話すことはできませんが、リレーショナルデータベースでは1つの操作しか有効にできません。ただし、これは操作が何であるかに帰着します。
たとえば、2人のユーザーが同じオブジェクトを変更しようとしたとします。それらの変更が列のサブセットのみを変更する場合、たとえば...
ユーザー1:
update MyTable set Col1 = '1', Col2 = '2' where ID = 'abc'
ユーザー2:
update MyTable set Col2 = 'x', Col3 = 'y' where ID = 'abc'
確実Col1
に「1」になり、Col3' will be 'y', as those two columns were only updated in one statement. The value of
Col2`は最後に実行されたコマンドによって決定されます。
同様に、あるユーザーが行を更新し、別のユーザーが行を削除した場合、その行は何があっても削除されます。ユーザーの更新コマンドが最初に来た場合、更新は成功し、行は削除されます。削除コマンドが最初に来た場合、行は最初に削除され、行が存在しないため、更新は何もしません(where
句はどの行とも一致しません)。
ただし、実際には、変更された列のみを含むコマンドを使用してデータベースに更新を発行することを気にするアプリケーションはほとんどありません。ほとんどすべてのアプリケーションでは、コマンドはテーブルレベルで作成され、すべての列を更新してから、「現在の」(変更されているかどうかに関係なく)値がこれらのコマンドに渡されます。これが、楽観的同時実行性を使用する理由です。
abc
その行に現在値があると仮定します。
ID = 'abc'
Col1 = '1_original'
Col2 = '2_original'
Col3 = '3_original'
また、両方のユーザーが同時に行を取得した場合、上記のコマンドはより現実的に次のようになります。
ユーザー1:
update MyTable set Col1 = '1', Col2 = '2', Col3 = '3_original' where ID = 'abc'
ユーザー2:
update MyTable set Col1 = '1_original', Col2 = 'x', Col3 = 'y' where ID = 'abc'
今、問題があります。2番目のコマンドは実際にはの値を気にしませんがCol1
、ユーザー1によって設定された値を上書きする可能性があります。同様に、ユーザー2が最初にヒットした場合、ユーザー1はCol3
ユーザー2によって書き込まれた値を上書きします。
楽観的同時実行性は、基本的に句を拡張して、テーブルのキーだけでなく、すべてwhere
の列の値をチェックします。このようにして、行を取得してから保存し直すまでの間に、他の誰か(または何か)によって行われた変更を上書きしないようにすることができます。
したがって、同じ条件が与えられると、コマンドは次のようになります。
ユーザー1:
update MyTable set Col1 = '1', Col2 = '2', Col3 = '3_original' where ID = 'abc'
and Col1 = '1_original' and Col2 = '2_original' and Col3 = '3_original'
ユーザー2:
update MyTable set Col1 = '1_original', Col2 = 'x', Col3 = 'y' where ID = 'abc'
and Col1 = '1_original' and Col2 = '2_original' and Col3 = '3_original'
つまり、列が元の値を持たなくなるため、データベースに最後にヒットしたコマンドは実際には何も実行されません。