У меня проблема с блокировкой с двумя транзакциями, которые не имеют доступа к каким-либо общим записям. Также не существует эскалации блокировки. Поэтому я не могу объяснить, почему возможен тупик.SqlServer 2005: проблема взаимоблокировки без общих записей
Тупик возникает, когда два таких операций выполняются одновременно:
begin transaction
update A set [value] = [value]
where id = 1; /* resp. 2 */
/* synchronize transactions here */
SELECT *
FROM
A inner join B on A.B_FK = B.id
inner join C on C.A_FK = A.id
WHERE
A.[value] = 1; /* resp. 2 */
rollback;
Эти таблицы и данные для настройки сценария:
CREATE TABLE A (
id INT NOT NULL,
[value] INT,
B_FK INT
primary key (id)
)
CREATE TABLE B (
id INT NOT NULL,
primary key (id)
)
CREATE TABLE C (
id INT NOT NULL,
A_FK INT
primary key (id)
)
INSERT INTO A VALUES(1, 1, 1)
INSERT INTO B VALUES(1)
INSERT INTO C VALUES(1, 1)
INSERT INTO A VALUES(2, 2, 2)
INSERT INTO B VALUES(2)
INSERT INTO C VALUES(2, 2)
Таблица A
находится в середине три таблицы. Если я изменю что-либо в запросе, например, удалите одну из объединенных таблиц B
или C
, нет тупика. То же самое, когда я фильтрую на A.id
вместо A.value
.
График взаимоблокировки говорит мне, что они оба хотят установить блокировку S на индекс первичного ключа таблицы A
. Опять же: эскалации блокировки нет.
Я использую SqlServer 2005.
- Почему эти сделки противоречат друг другу без доступа к любым общим данным? Может кто-нибудь объяснить это?
- Что можно сделать, чтобы избежать этого? Я использую NHibernate и не могу легко изменить запрос.
- Может быть проблема с SqlServer?
Большое спасибо.
что делать "/ * синхронизация сделка здесь * /" означает? –
@Mitch: Это означает, что я выполняю транзакцию 1 до этой точки, затем выполняю транзакцию 2, которая ждет выбора, затем я запускаю транзакцию 1 до конца, которая также ждет выбора. –