Информация об изменениях

Сообщение Re: Вопрос про транзации и deadlocks от 08.07.2015 14:13

Изменено 08.07.2015 14:30 Tigor

Здравствуйте, Divineshadow, Вы писали:

D>Используемый IsolationLevel = Serializable — и понятно, что когда таблица занята транзакцией из одного потока, то другой не может к ней обратиться.

D>Вернее он ждёт её освобождения. По крайнее мере я так понимаю принцип работы транзакций с уровнем Serializable.

Это не совсем так. А точнее, совсем не так.
MS SQL сервер реализует так называемую оптимистик конкарренси. Об этом лучше почитать, но если совсем на пальцах, то Serializable (то есть иллюзия последовательного выполнения транзакций) гарантируется не их реальным последовательным выполнением, а откатом всех конфликтующих транзакций кроме одной, когда что-то пошло не так.
Что Вы и наблюдаете.

Чтобы залочить таблицу целиком, придется использовать хинт (как один из вариантов).
Вам оно точно нужно? Нельзя использовать идентити колонку?
Сорри, исправляюсь, identity колонка и так есть и вторая колонка строковая.

Можете добавить уникальный индекс на вторую колонку?
Это должно несколько помочь.
Еще можно совместить проверку на существование и добавление новой строки в один оператор.
Это может помочь еще чуть-чуть засчет увелечения скорости выполнения.

Уникальному индексу вообще очень хорошая штука в данном случае,
можете снизить уровень изоляции транзакции и просто игнорировать исключения о попытке нарушить уникальность индекса.

Еще есть оператор merge.
Re: Вопрос про транзации и deadlocks
Здравствуйте, Divineshadow, Вы писали:

D>Используемый IsolationLevel = Serializable — и понятно, что когда таблица занята транзакцией из одного потока, то другой не может к ней обратиться.

D>Вернее он ждёт её освобождения. По крайнее мере я так понимаю принцип работы транзакций с уровнем Serializable.

Это не совсем так. А точнее, совсем не так.
MS SQL сервер реализует так называемую оптимистик конкарренси. Об этом лучше почитать, но если совсем на пальцах, то Serializable (то есть иллюзия последовательного выполнения транзакций) гарантируется не их реальным последовательным выполнением, а откатом всех конфликтующих транзакций кроме одной, когда что-то пошло не так.
Что Вы и наблюдаете.

Чтобы залочить таблицу целиком, придется использовать хинт (как один из вариантов).
Вам оно точно нужно? Нельзя использовать идентити колонку?
Сорри, исправляюсь, identity колонка и так есть и вторая колонка строковая.

Можете добавить уникальный индекс на вторую колонку?
Это должно несколько помочь.
Еще можно совместить проверку на существование и добавление новой строки в один оператор.
Это может помочь еще чуть-чуть засчет увеличения скорости выполнения.

Уникальному индексу вообще очень хорошая штука в данном случае,
можете снизить уровень изоляции транзакции и просто игнорировать исключения о попытке нарушить уникальность индекса.

Еще есть оператор merge.