@Transactional
public void selectAndUpdate() {
status = select ... for update;
if(status!="初始值") {
return;
}
//逻辑开始
程序逻辑 ...
举例:用户支付
1.生成用户签名
2.发起用户支付到第三方
//逻辑结束
update status语句...
}
如果利用这种方式来控制并发会有什么问题?另外我还想问大家的是:多个线程的话,会不会导致当一个线程执行到程序逻辑那块的时候,资源被另一个线程抢去的可能?导致另一个线程进入这个方法,发现状态还是没有被改变,然后又进入程序逻辑这块,导致两个线程都执行了一遍吗?数据库的一个事务没有完成的话,会让另外一个线程的事务进入吗?
for update
の欠点 @Hisoka は、他のスレッドをブロックすることに加えて、ロック プロセスによってデータベースに多大なパフォーマンス損失が生じるとすでに述べています。for update
したがって、問題を解決するには楽観的ロックを使用することをお勧めします。プログラム ロジックはメモリ内で動作し、元のデータが関与しないため、ステートメントの状態を制御するためにのみ楽観的ロックを使用する必要があります。 ...こちら
update status
このメソッドは同時実行制御を実現するために悲観的ロックを使用します。また、nowait を使用しない更新では、スレッドが待機し、ロックを追加した後にすぐに失敗します。さらに、トランザクションには分離レベルと伝播動作の設定があり、詳細を知るための情報を見つけることをお勧めします。
for update は、同時実行性が高いシナリオの問題を解決するために使用され、分散ロック メカニズムを使用して実装されます。最初の for update ステートメントが実行されると、後続の SQL ステートメントはスリープ状態になり、最初の SQL ステートメントのコミットが正常に実行および送信されるまで待機してから、次のステートメントの実行に戻ります。