基本的にETLタスクを実行するlinq-to-sqlプログラムを作成しましたが、並列化によってパフォーマンスが向上する場所がたくさんあることに気づきました。ただし、2つのスレッドが次のタスク(疑似コード)を実行するときに、一意性制約違反を防ぐことが心配です。
Record CreateRecord(string recordText)
{
using (MyDataContext database = GetDatabase())
{
Record existingRecord = database.MyTable.FirstOrDefault(record.KeyPredicate());
if(existingRecord == null)
{
existingRecord = CreateRecord(recordText);
database.MyTable.InsertOnSubmit(existingRecord);
}
database.SubmitChanges();
return existingRecord;
}
}
一般に、このコードは、SELECT
レコードの存在をテストするステートメントを実行し、その後にINSERT
レコードが存在しない場合はステートメントを実行します。暗黙のトランザクションによってカプセル化されます。
2つのスレッドがの同じインスタンスに対してこのコードを実行する場合recordText
、レコードが存在しないことを同時に判断して、両方が同じレコードを作成しようとするのを防ぎたいと思います。分離レベルと明示的なトランザクションはうまく機能しますが、どの分離レベルを使用Serializable
すべきかわからない場合は、機能するはずですが、厳密すぎるようです。より良い選択肢はありますか?