Похоже, это просто состояние гонки между двумя соединениями, выполняющими чтение / вставку. Одним из исправлений может быть создание сериализуемой транзакции вокруг двух операций:
using (var tran = new TransactionScope()) {
using (MyDataContext db = new MyDataContext()) {
// ... your existing code here
}
tran.Complete();
}
Это вызывает блокировку диапазона клавиш во время выбора, поэтому любой второй поток, выполняющий чтение, будет заблокирован до завершения транзакции; поэтому вы не получите два SPID, которые видят «без строки», а затем пытаются выполнить вставку; вместо этого первый SPID будет блокировать второй на несколько критических миллисекунд, пока он выполняет свою работу; только когда первый SPID решил, следует ли (или нет) вставить данные (и вызвать Complete
или выполнить откат), второй SPID узнает.
Также обратите внимание, что вам не нужно менять первичный ключ, чтобы сделать его уникальным - просто добавьте уникальное ограничение. Тогда вам не нужно ничего менять , ссылаясь на эту таблицу.