Допустимы ли долгосрочные транзакции?
Я думаю об использовании транзакций в двухуровневых приложениях WPF (или Windows Forms) следующим образом:
Мы можем начать новую транзакцию, когда откроем новую форму для редактирования данных, отредактируем и сохраним изменения прозрачно в этой транзакции. Затем мы можем нажать кнопку "ОК" и зафиксировать транзакцию или кнопку "Отмена" и откатить ее. Если мы хотим открыть другое диалоговое окно с этими данными, мы можем использовать вложенные транзакции.
Вопрос в том, приемлем ли этот способ использования транзакций или нет? Я знаю, что существует много разных способов реализации такой логики, но я хотел бы перечислить преимущества и недостатки этого.
5 ответов
Вот несколько проблем, с которыми вы можете столкнуться, если вы пойдете этим путем
- сброс соединения / закрытие /тайм-аут (если пользователь идет в ванную)
- конфигурация базы данных (база данных в основном предварительно сконфигурирована для многих коротких транзакций, а не длинных. Например, может потребоваться настройка журнала отмены, который отслеживает, что было сделано во время передачи)
- проблемы сблокировками, даже, возможно, взаимные блокировки (чем дольше транзакции, тем больше шансов, что одна и та же блокировка будет получена дважды, возможно, в конфликтном порядке)
Это обескураженная практика. Вместо этого используйте оптимистическую блокировку. Читайте данные при необходимости, сохраняйте копию в памяти. Когда диалог закрыт, попытайтесь синхронизировать изменения с базой данных. Если данные были изменены в базе данных между ними, действие отменяется. Вероятность неудачи зависит от количества пользователей и т. Д. Но на практике это часто приемлемо.
Долгоживущие транзакции были темой для горячей дискуссии в академических кругах примерно... 1980-х, я бы сказал Проблема заключается в том, что долгоживущая транзакция почти наверняка создает тупик в пессимистичном исполнении и почти наверняка требует сложного разрешения конфликтов в оптимистическом исполнении (номера можно найти в статье Джима Грея "Опасности репликации и решения", но вскоре взаимные блокировки увеличиваются как пятая степень размера транзакции, а вероятность столкновения возрастает как вторая степень).
Теперь были разные предложения по этой проблеме, такие как "саги" из Салема и Гарсиа-Молина, "вложенные транзакции" и так далее ( еще одна статья Джима Грея "Концепция транзакций: достоинства и ограничения" содержит несколько страниц об этом в конце), Большинство предложений касаются модели транзакций, более слабой, чем ACID. Например, "длинным транзакциям", возможно, придется выставлять свои промежуточные результаты, что нарушает свойство изоляции. Но ни одно из предложений так и не попало в отрасль, так сказать. Главным образом потому, что эти методы на самом деле не... упрощали и не были необходимы для решения реальных бизнес-задач.
Итак, чтобы ответить на ваш вопрос: нет, долгоживущие транзакции не приветствуются в основных движках БД.
Длительные транзакции серьезно повлияют на вашу способность масштабироваться.
Я бы избежал, если это вообще возможно.
Как уже отмечали другие, вы не должны держать транзакцию открытой во время ожидания ввода пользователя.
НЕТ, не держите транзакцию открытой во время ожидания ввода пользователя. Это плохой дизайн и приведет к проблемам с блокировкой ваших транзакционных ресурсов (базы данных).
Вы должны переосмыслить свой подход. Зачем открывать транзакцию, когда пользователь заполняет форму? Мы используем транзакции для управления параллелизмом и блокировками на общих ресурсах. Заполнение формы на самом деле не подходит.
Я согласен с Mitch n Cheeso, но все же есть еще один способ поставить Timeout в окне, вы можете уведомить часы, что если пользователь не нажмет "ОК", то окно будет закрыто автоматически и все будет отменено.
Большинство систем, где транзакции имеют решающее значение, такие как процесс "Резервирование" в авиакомпании, фильмы и т. Д., Операторы должны закрывать транзакции в ограниченное время.