Нет, два сеанса не могут обновлять одну и ту же строку одновременно.Блокировка на уровне строк настолько низка, насколько это возможно, когда один сеанс обновляет строку, другие сеансы, желающие обновить эту запись, будут ждать.
Что касается взаимоблокировок, проблема с SQL Server заключается в том, что по умолчанию операторы SELECTбудет заблокирован, если он запрашивает запись, которая в данный момент обновляется.Вы можете использовать WITH (NOLOCK), если не возражаете против чтения незафиксированных данных.
Итак, если у вас есть такой порядок событий: SessionA
begin transaction
update t1
set c1 = 'x'
where c2 = 5
SessionB
begin transaction
update t2
set c1 = 'y'
where c2 = 7
SessionA
select * from t1 where c2 = 5
<waits on SessionB>
SessionB
select * from t2 where c2 = 7
<waits on SessionA>...oops. Deadlock.
Хитрость заключается только взаблокируйте что-то на минимальное время, необходимое для этого (не разбивайте последовательность операторов только для снятия блокировки - убедитесь, что шаги, составляющие логическую транзакцию, остаются транзакцией):
begin transaction
update t1
set c1 = 'x'
where c2 = 5
commit
Или (caveat emptor) используйте директиву nolock:
SessionA
select c1 from t1 where c2 = 5 with (nolock)
<gets the new value of 'x'>
SessionB
select * from t2 where c2 = 7 with (nolock)
<gets the new value of 'y'>