電子メールが 1 回だけ送信されるようにしたいので、Oracle SQL で次のステートメントを使用しています。
update mytable set mail_sent = 't' where id = ? and mail_sent = 'f'
変更された行数を調べます。行が変更されていない場合、別のプロセスが最初に同じことを行い、メールを送信します。1 行が変更された場合、メールを送信します。(もちろん、メールの送信に失敗した場合は、mail_sent をリセットします。プロセスがクラッシュして mail_sent が 't' のままになる可能性がわずかにあるため、メールは送信されません。それで我慢します。)
これが競合状態に対して安全であると確信することはできません (プロセス 1 が 'f' を読み取り、プロセス 2 が 'f' を読み取り、プロセス 1 が 't' を書き込む前に、両方のプロセスが行を変更したと見なし、2 つの電子メールが送信されます。問題を回避するために分離レベルを SERIALIZABLE に設定していますが、これは実際に必要ですか、それなしでも安全ですか?