Могу ли я открыть остановленную транзакцию с SQL Server? - PullRequest
4 голосов
/ 02 августа 2011

Я ищу что-то похожее на транзакцию SQL.Мне нужны обычные средства защиты, которые обеспечивают транзакции, но я не хочу, чтобы это замедляло кого-либо еще.

Представьте, что клиент A подключается к БД и выполняет следующие команды:

BEGIN TRAN
SELECT (something)
(Wait a few seconds maybe.)
UPDATE (something)
COMMIT

InbetweenSELECT и UPDATE, клиент B приходит и пытается выполнить запрос, который в нормальных обстоятельствах в конечном итоге должен был бы ждать, пока A не завершится.

Я хотел бы, чтобы клиент A открылэто транзакция таким образом, что если B придет и выполнит свой запрос, клиент A обнаружит, что его транзакция немедленно откатывается, а последующие команды не выполняются.Клиент B будет испытывать только минимальную задержку.

(Обратите внимание, что SELECT и UPDATE - просто иллюстративные команды.)

Обновление ...

У меня высокий приоритетзадача (клиент B), которая иногда (раз в месяц) получает ошибку тайм-аута SQL, и задача с низким приоритетом (клиент A) с транзакцией, которая вызывает этот тайм-аут.Я бы предпочел, чтобы задача с низким приоритетом завершилась неудачно и была предпринята попытка в следующем цикле.

Я решил исправить эту проблему, полностью исключив транзакции и заменив их неформальным набором флагов.Запросы подвергались рефакторингу только для того, чтобы что-то делать, если был поднят правильный набор флагов, и я добавил что-то, что очистило заброшенные записи, что откат мог очистить в прошлом.

Я исправил проблемы с транзакциями, исключив транзакции.

Ответы [ 4 ]

6 голосов
/ 02 августа 2011

Использование SNAPSHOT уровня изоляции предотвратит блокировку B. B увидит данные в том состоянии, в котором они были до A выданного BEGIN TRANSACTION. Если B не изменит данные, они никогда не будут блокировать друг друга.

2 голосов
/ 02 августа 2011

Хотя вовсе не транзакция , Оптимистичный параллелизм может быть полезным - он используется по умолчанию в LINQ2SQL и т. Д.

Общая идея заключается в том, что данные читаются - модификации могут быть сделаны независимо - и затем данные записываются с «проверкой» (это слабо сопоставимо с «Сравнить» и «Поменять местами»). Если проверка не удалась, приложение должно решить, что делать (перезапустить процесс, продолжить в любом случае, потерпеть неудачу).

Это, естественно, не работает для всех сценариев и может не обнаруживать ряд взаимодействий, таких как новые элементы, добавленные между «чтение» и «запись». И фактическое чтение и запись могут быть в отдельных транзакциях с соответствующим уровнем изоляции; отдельные транзакции могут разрешать чередование дополнительных транзакций.

Конечно, в зависимости от конкретной проблемы и взаимодействий ... может быть достаточно разных уровней изоляции и / или более тонкой блокировки.

Удачного кодирования.

2 голосов
/ 02 августа 2011

Это задом наперед.

Нельзя, чтобы более поздние клиенты прерывали более ранние транзакции: это хаос.

Вы можете иметь изоляцию моментального снимка , чтобы клиент B имел согласованное представление и не был заблокирован(в основном) клиентом A. Также Википедия для более общих вещей

Возможно, опишите вашу проблему более полно, чтобы мы могли предложить предложения для этого ...

1 голос
/ 02 августа 2011

Одна вещь, которую я видел, использовала (но я боюсь, что у меня нет кода, пригодного для этого) - это транзакция A порождает другой процесс, который затем отслеживает транзакцию.Если он обнаружит какие-либо блоки, вызванные транзакцией, он немедленно выдаст spid KILL.

Если я найду код для этого, я добавлю его сюда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...