回答:
あなたの質問は本当にデータベースにとらわれていないと思います。正しい答えは、実装の詳細に依存する可能性があります。これは、ベンダーごとに異なり、次のバージョンで変わる可能性があります。RDBMSでアプローチを選択する前に、同時実行でテストします。
現在、SQL Server 2008 R2では、以下を使用しています。
同時実行性が低く、変更量が少ない。単一の行を保存するには、sp_getapplockを使用してシリアル化し、MERGEを使用します。それが機能することを確認するために、高い並行性の下でストレステストを行います。
より高い同時実行性および/またはボリューム。並行性を回避し、パフォーマンスを向上させるために、一度に1行は保存しません。アプリサーバーに変更を蓄積し、TVPを使用してバッチを保存します。それでも、同時実行に関連する問題を回避するために、MERGEの前にsp_getapplockを使用してシリアル化します。繰り返しますが、私はそれが機能することを確認するために、高い並行性の下でテストを強調します。
その結果、本番環境ではパフォーマンスが高く、同時実行性に関連する問題はありません。デッドロック、PK /一意制約違反などはありません。
DBにエラーを発生させます。
2つのスレッドが "NOT EXIST"を渡し、両方が書き込みを試みるため、最終的に衝突が発生するため、最初のテストは同時実行性に対して安全ではありません。これは、「READ COMMITTED」とMVCC / Snapshotロック戦略の両方に適用されます。
ロックヒントを使用して強制的に分離できますが、パフォーマンスは低下します。
これをJFDIパターン(SOリンク)と呼びます。「存在する場合は更新」については、こちらをご覧ください。SQLServer 2005のデッドロックシナリオのトラブルシューティングが必要です。これらはSQL Serverです。MySQLには、これを適切に処理するINSERT IGNOREがあります。残りはわからない
MERGE
、Paulの見解を解決した可能性のあるものがありますが、これを高い送信レートでテストしていません。その構文を理解するように脳を訓練する必要があるためです。