Serviceを読んで理解し、同意したものとみなします。スタック・オーバーフローはプログラマーとプログラミングに熱心な人のためのQ&Aサイトです。400件10データベースでトランザクションを実行してテーブルにselectを行い、データが存在しないことを確認した上でinsert処理を行う場合に並列でほぼ同時にトランザクションが走ると、お互いにコミットされていないためselectでの存在チェックをすり抜け、insert処理が複数実行されてしまうケースを改善するためにはトランザクションレベルを上げるか、またはテーブルに対してデータが重複しないようにユニークキーを設定するしかないのでしょうか?アプリケーションレベルでの回避は困難なのでしょうか?追記RDBMSを使用し(出来ればMysqlかPostgres)、PKをAUTO_INCREMENTに設定している場合です。ユニークキーを設定した場合や、テーブルロックを行った場合は重複が防げると理解しているのですが、それ以外の方法で回避する方法はないのか知りたいです。updateを使用すれば該当の行のみをロックすることができますが、insertの場合は対象の行が存在しないため行レベルでのロックが行えないため、ロックするにしてもテーブルロックしか方法がないのかと思っています。アプリケーションレベルでのトランザクション内で更新とチェックはよくあることだと思うのですが、それに対して他のアプローチや回避策がないかと思い質問させて頂きました。RDBMSの機能を一切使わないわけではありません。個の銅バッジトランザクションレベルはアイソレーションレベルの間違いですね。UPDATE文でロックするのが良いでしょう。ロックを使いたくない何らかの理由があれば、行にバージョンカラムを設けて、更新されるたびにカウントアップします。UPDATE時にPK+当該のカウントの行が存在しなければ誰かが先にUPDATEしたと判断できます。オプティミスティックロックで検索してみてください。17:01早速のご回答ありがとうございます。17:14重複しているレコードがすでに存在していることを挿入前にアプリケーションが検出出来なければならないのか、結果として重複したレコードが出来なければよいのか、どちらでしょうか。RDBMSにこだわらない方法が必要なのか、特定のRDBMSを前提としているのかどちらでしょうか。DBで実装されている機能を自分で実装しても、バグってないかなぁ?と心配事が増えるだけな気がしたので。0:16レコードが存在しない時に排他制御したい例は滅多にないので読み飛ばしてしまいました。普通はPKエラーになってINSERTできませんから。INSERTが重複してしまうということはPKが正しくセットされていないか、PKをAUTO_INCREMENTとかtimestampにしているからでは?その場合何をもってして重複だと判断していますか?その条件に従ってUNIQUE制約を設定すれば良いと思います。具体的な例を書いてもらえると助かります。票3質問文で除外されいてるパターンも含めて整理し直します。「selectでの存在チェック」と同じ内容でユニークキーを設定することでINSERT時に自動的に存在チェックを行うことができます。「selectでの存在チェック」が不要になるため効率がいいです。「selectでの存在チェック」が複雑でユニークキーを設定できない場合、TRIGGERを設定することで、INSERT時に自動的に存在チェックを行うことができます。アプリケーション側からの明示的な「selectでの存在チェック」が不要になるため効率がいいです。MERGE文を使用することで存在しない場合にのみINSERTを行うことができます。同時に存在する場合にUPDATEやDELETEを行うこともできます。事前にテンポラリテーブルなどに格納する必要があったり、対応しているデータベースエンジンが限られます。「selectでの存在チェック」の内容をON句に記述するため、そうであればそもそもユニークキーが設定できそうです。トランザクション分離レベルを上げることでファントム読み取りを防止します。「selectでの存在チェック」を行うとデータベースによって「INSERT予定の行が存在しないこと」も保証され、複数実行は防止されます。(ただし範囲ロックが使われるため偽の失敗が発生します...だっけ?)テーブルロックを行うことで、根本的に複数実行を防止します。アプリケーションによる解決アプリケーションレベルで排他処理を行うことで、根本的に複数実行を防止します。個の銅バッジ1トランザクションを用いることでアプリケーション側で一貫性のチェックを行うのは極一般的な用法ですが、何か勘違いされていませんか。「アプリケーションで排他制御を行えばアプリケーションレベルで一貫性はチェック出来る」は確かに事実ですが、トランザクションというかデータベースそのものの存在意義を否定してしまっています。「データベースレベルで一貫性チェックを行わない」というデータベースの存在意義のかなり否定した条件下での回答であり、一般論を答えたものではありません。「データベースレベルでトランザクションを使用するのであればデータベースレベルで一貫性をチェックすべきです。事を気にしているのかもしれないし、単なる興味本意なのかもしれないし、その他思いもよらない事なのかもしれない。そこを各解答者が自分の想像力で思い思いに埋めて答えてるんだと思いますが、周りが色々書いてるだけで肝心の質問者が何も反応しないし。個人的には、こういう考え方もあるんだなという事が分かっていいかなと思いますし、説明考えるのも好きでやっているので問題ないです。それと後から第3者が見ても役に経つ可能性はあるのかなと思います。このサイトの主旨に合っているかは分かりません。いう点においては質問が分かりにくいです。分かりにくいのは仕方ないと思います。誰だって思い込みとかあって、自分の文章を他人が読んでどう思うかまで想像できないですから。質問者はもっと解答に反応して欲しいと思います。ならないのは、そうしようと思わせない空気がココにあるからかもしれません。なんかこういう人達とやりとりしたくないなと思われちゃったとか。いう場合は、ネット上で一見さんの空気を読むのは不可能に近いと思うので、仕方ないのかもしれません。質問者が実名でも固定ハンドルネームでもないので放置しているだけないかもしれないです。13:17繰り返しますが、データベースではなくアプリケーションレベルで一貫性のチェックを行うことは一般的によくあります。この場合、普通は更新とチェックを一つのトランザクションとして処理します。これが一般的な状況でないと言われるのなら見解の相違としか言いようがないですね。トランザクションをどのように定義するかはアプリケーションレベルの話で、それがどのような意図なのかはDB側は知ったことではありません。かかわらず意図によって良い悪いがあるのだ、制約をアプリケーションで実装するのに使ってはならないというのは不合理でしょう。回答スタック・オーバーフローに参加してくれて、ありがとうございます!質問の回答を共有してください。回答を説明し、自分の検討結果も共有してください。意見を述べること(意見を述べるなら、参照リソース、自分の経験で意見をサポートしてください)さらにサポートが必要な場合このヘルプを参考してください。“回答を投稿”をクリックすることで利用規約、プライバシーポリシー、及びクッキーポリシーに同意したものとみなされます。タグが付いた他の質問を参照するか、自分で質問をする。質問のフィードこのRSSフィードを購読するには、このURLをコピーしてRSSリーダーに貼り付けてください。