2010-10-13 2 views
1

У меня есть запрос linq, выполняемый в веб-службе WCF, который ищет совпадение, а если он не найден, он создает его.LINQ Вставка в базу данных привела к дублированию

мой код выглядит

//ReadCommitted transaction 
    using (var ts = CreateTransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
    Contract contract = db.Contracts.SingleOrDefault(x => x.txtBlah == str); 
    if (contract == null) 
    { 
     contract = new Contract(); 
     contract.txtBlah = str; 
     db.Contracts.InsertOnSubmit(contract); 
     db.SubmitChanges(); 
    } 
    ... 
    db.SubmitChanges(); 
    } 

Проблема заключается в том, что я получаю дубликаты. Я думал, что транзакция заблокировала бы базу данных, чтобы не было обнаружено дубликатов (и обеспечить возможность отката). Как я могу гарантировать, что дубликатов нет?

ответ

0

В транзакции ReadCommited данные могут быть изменены до завершения транзакции. Но вы можете использовать транзакцию Serializable, которая будет выполнять блокировку таблицы.

db.Connection.Open(); 
using (db.Transaction = db.Connection.BeginTransaction(IsolationLevel.Serializable)) 
{ 
//your code here 
db.Transaction.Commit(); 
} 

Хорошо, если вы не хотите использовать Serializable Tran, то вы должны написать sproc для атомной вставки, логика должна выглядеть следующим образом SQL в коде:

db.ExecuteCommand("INSERT INTO Contract (txtBlah) SELECT {0} WHERE NOT EXISTS (SELECT 1 FROM Contract WITH (TABLOCK) WHERE txtBlah={0})", str); 

ноты это также заблокирует всю таблицу во время вставки.

Подробнее о том, как создать sproc без условия гонки на http://weblogs.sqlteam.com/dang/archive/2007/10/28/Conditional-INSERTUPDATE-Race-Condition.aspx.

+1

, который будет блокировать КАЖДОЙ вызов вокруг этой области. Могу ли я заблокировать только части вставки? aka блокировать сериализуемые транзакции внутри транзакции readcommitted? – BabelFish

+0

aka Могу ли я получить BeginReadCommitTran {DoSomeFunctions; BeginSerializableTran {Insert; Commit; } DoMoreFunctions; Commit; } Если это имеет смысл – BabelFish

+0

Поместите только выбор и вставку в Serializable tran или напишите sproc для него. – jomi

Смежные вопросы