我已经写了一个基本上执行ETL任务的linq-to-sql程序,并且我注意到许多并行化将提高其性能的地方。但是,我担心在两个线程执行以下任务(伪代码)时防止出现唯一性约束违规。对于以下insert-if-present事务,我应该使用哪种隔离级别?
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
声明如果记录不存在。它被隐式事务封装。
当两个线程为recordText
的同一个实例运行此代码时,我想阻止它们同时确定该记录不存在,从而同时尝试创建相同的记录。隔离级别和显式事务将运行良好,除非我不确定我应该使用哪个隔离级别 - Serializable
应该可以工作,但似乎太严格了。有更好的选择吗?