我编写了一个实质上执行 ETL 任务的 linq-to-sql 程序,并且我注意到并行化可以提高其性能的许多地方。但是,当两个线程执行以下任务(伪代码)时,我担心防止违反唯一性约束。
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
应该工作,但似乎太严格了。有更好的选择吗?