Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Уровень изоляции в транзакции  [new]
unsafe
Member

Откуда:
Сообщений: 55
Привет.
Я не знаток касаемо уровней изоляции. Если честно никогда их даже не использовал. Пользуемся на работе EF, и насколько я знаю он всегда выполняет запросы с помощью транзакций. По умолчанию, это уровень ReadCommited. Можно всегда переписать заявку на SQL вместо использования EF2SQL, но мне принципиально важно понять как точно не ошибиться с уровнем изоляции.
Задача с которой я столкнулся заключается в следующем:
Есть две таблицы, Passengers и Transfers. В таблице Transfers есть поле PassengersSeats, которое отвечает за максимально кол-во пассажиров. При попытке добавления нового пассажира, мы должны проверить равно ли текущее кол-во пассажиров закреплённое за трансфером со значением в поле PassengersSeats. Если это так, то надо увеличить значение в поле PassengersSeats, после чего добавить пассажира.
Выходит мы должны синхронизировать чтение из таблицы Passengers, что бы при попытке посчитать текущее кол-во пассажиров мы не получили неверные данные.
Подскажите, какой уровень изоляции использовать.
19 янв 18, 12:43    [21119788]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
unsafe
Member

Откуда:
Сообщений: 55


К сообщению приложен файл. Размер - 5Kb
19 янв 18, 12:44    [21119795]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5112
unsafe
Выходит мы должны синхронизировать чтение из таблицы Passengers, что бы при попытке посчитать текущее кол-во пассажиров мы не получили неверные данные.
repeatable read
19 янв 18, 13:01    [21119884]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4535
unsafe, в случае с иэф ваша задача ни как (зависит от реализации) с транзакциями не связана. Ищите по словам ef rowversion concurrency
19 янв 18, 13:38    [21120074]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
unsafe
Member

Откуда:
Сообщений: 55
Дедушка,
Я руководствовался следующей статьёй. У нас в рамках одной транзакции будут следующие запросы.
1) select * from Transfers where Id = @transfersId
2) select count(*) from passengers where Id = @transfersId
после чего вариант insert+update или только insert
3) insert into Passengers ...
||
3) update Transfers
set PassengerSeats = PassengerSeats + 1
where Id = @transfersId
4) insert into Passengers ...

Мне стало интересно, а в каком случае у нас будет максимальные уровень изоляции, то есть Serializable? Только если в рамках одной транзакции мы будем повторно запрашивать данные?

buser, Почему не связана? Если повысить уровень изоляции можно же избежать не консистентного чтения/записи
19 янв 18, 14:56    [21120534]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7399
unsafe,

я думаю, что вам нужен Serializable, т.к. другим процессам даже читать нельзя из колонки счетчика, пока не закончится операция. Так как они тоже захотят обновить счетчик. Потенциально такой архитектурой вы создали "бутылочное горлышко".
19 янв 18, 15:22    [21120675]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4535
Владислав Колосов, а почему не снапшот?
19 янв 18, 15:34    [21120743]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
unsafe
Member

Откуда:
Сообщений: 55
Владислав Колосов, Как вы считаете, как было бы лучше спроектировать?
19 янв 18, 15:37    [21120758]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
unsafe
У нас в рамках одной транзакции будут следующие запросы.
1) select * from Transfers where Id = @transfersId
2) select count(*) from passengers where Id = @transfersId
после чего вариант insert+update или только insert
3) insert into Passengers ...
||
3) update Transfers
set PassengerSeats = PassengerSeats + 1
where Id = @transfersId
4) insert into Passengers ...
Если делать так:
begin tran;

update t
 set
  PassengerSeats += case when t.PassengerSeats > c then 0 else 1 end
from
 Transfers t cross apply
 (select count(*) from Passengers where transfer_id = t.id) p(c)
where
 t.id = @transferid;

insert into Passengers ...

commit;
То можно обойтись read committed. Соответственно, удаление из Passengers должно быть реализовано по такому же принципу.
19 янв 18, 16:14    [21120931]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции в транзакции  [new]
aleks222
Guest
invm
unsafe
У нас в рамках одной транзакции будут следующие запросы.
1) select * from Transfers where Id = @transfersId
2) select count(*) from passengers where Id = @transfersId
после чего вариант insert+update или только insert
3) insert into Passengers ...
||
3) update Transfers
set PassengerSeats = PassengerSeats + 1
where Id = @transfersId
4) insert into Passengers ...
Если делать так:
begin tran;

update t
 set
  PassengerSeats += case when t.PassengerSeats > c then 0 else 1 end
from
 Transfers t cross apply
 (select count(*) from Passengers where transfer_id = t.id) p(c)
where
 t.id = @transferid;

insert into Passengers ...

commit;
То можно обойтись read committed. Соответственно, удаление из Passengers должно быть реализовано по такому же принципу.


Если внимательно прочитать бред тредстартера:

1. Вставляем в Passengers
2. Обновляем PassengerSeats = (select count(*) from Passengers where transfer_id = t.id)
3. И не парим отсутствующий мозг.
19 янв 18, 17:56    [21121303]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить