同時に4億スレッドで次のことを行う必要があります(おそらく2スレッドに近いですが、どちらの方法でも...):そのようなものが存在しない場合は、それを挿入します。
現在、アプリケーションは次のように述べています。
select rows from the db
if row count == 0,
do some stuff
insert a row
これが2つの別々のスレッドで同時に実行される状況があります。このように、2つのスレッドは、どちらかのスレッドが行を挿入する前に、それぞれが既存の行をチェックする可能性があります(実際にはこれまでのところ毎回実行されます)。したがって、重複する行があります。これは悪いです。
私が考えることができるすべてのアルゴリズムは、何らかの形で不十分です。
たとえば、これを行う場合:
open tx
insert a row
select rows
if row count > 2, rollback
else commit
トランザクションがREAD_COMMITTED
分離を使用する場合、1つのスレッドは別のスレッドの挿入された行を認識せず、重複する可能性があります。分離するとREAD_UNCOMMITTED
、各スレッドは他のスレッドの行を見ることができ、両方がロールバックします。MERGE
挿入してから選択する代わりにステートメントを使用すると(またはその逆)、同じ問題が発生すると思います。
上記のアルゴリズムを同時に実行したときに正確に1行が挿入されることを保証するために使用するアルゴリズムはありますか?FWIW、私はSpringでDB2、mybatis、およびxmlベースのtx管理を使用していますが、可能であれば他の何かから喜んで翻訳します。
私は並行性に関しては初心者なので、この質問で、あなたが知っている本や記事によって改善された無知が明らかになった場合は、共有してください。
編集:
上記の挿入ステートメントは、ユーザーが持っていない場合に、ユーザーに何かを怠惰に付与することです。この場合、一意性の制約が適切です。ただし、アプリの他の場所では適切ではありません。:(
わかりやすくするために、例をもう少し具体的にします。