Что произойдет, если вы не зафиксируете транзакцию в базе данных (скажем, SQL Server)?


108

Предположим, у меня есть запрос:

begin tran
-- some other sql code

А потом я забываю зафиксировать или откатиться.

Что произойдет, если другой клиент попытается выполнить запрос?

Ответы:


148

Пока вы не выполняете COMMIT или ROLLBACK транзакцию, она все еще "выполняется" и, возможно, удерживает блокировки.

Если ваш клиент (приложение или пользователь) закрывает соединение с базой данных перед фиксацией, все еще выполняющиеся транзакции будут отменены и прекращены.


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

12
Боковое примечание: при использовании Management Studio закрытие окна запроса приведет к закрытию соединения
Джо Филлипс,

3
@BradleyDotNET: да, определенно
marc_s

2
Имейте в виду, что SQL Server Management Studio автоматически фиксируется, если вы закрываете окно запроса / соединение по умолчанию.
Нуно

1
Обратите внимание, что, когда клиент закрывает соединение, пока транзакция активна, это не всегда откат - это зависит от клиента и базы данных. Например, когда приложение Java закрывает соединение с базой данных Oracle, любые открытые соединения автоматически фиксируются.
AviD

38

Вы можете попробовать это сами, это должно помочь вам понять, как это работает.

Откройте два окна (вкладки) в студии управления, каждое из которых будет иметь собственное подключение к sql.

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

Поиграйте с различными уровнями изоляции и отсутствием подсказок о блокировке, чтобы увидеть, как они влияют на результаты.

Также посмотрите, что происходит, когда вы выдаете ошибку в транзакции.

Очень важно понимать, как все это работает, иначе вы будете много раз озадачены тем, что делает sql.

Радоваться, веселиться! GJ.


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

16

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

Следовательно, если вы начнете, а затем не зафиксируете, произойдет откат при закрытии соединения (поскольку транзакция была прервана без пометки как завершенной).


Так и должно быть, но так бывает не всегда.
FalcoGer

... например, MyISAM из mySQL, который , конечно, не поддерживает транзакции.
Писквор покинул здание

3

зависит от уровня изоляции входящей транзакции.

Объяснение изоляции транзакций sql


6
Поведение транзакций не зависит от уровня изоляции. Количество блокировок, которые они могут вызвать, имеет значение.
marc_s

Я почти уверен, что то, какие данные могут быть прочитаны соединением, определенно зависит от уровня изоляции. Если у вас установлена ​​изоляция на READ UNCOMMITTED, вы можете читать данные, которые еще не зафиксированы, и на самом деле может быть откат в какой-то момент дорожки, но это гарантирует отсутствие блокировки. Если у вас установлен уровень изоляции READ COMMITTED, вы не можете читать незафиксированные строки - второй клиент зависнет, если вы не используете SNAPSHOT.
Xhalent 04

2

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


1

Пример транзакции

начать транссексуал

Ваши операторы sql

если произошла ошибка откатить tran tt иначе зафиксировать tran tt

Пока вы не выполнили фиксацию транзакции, данные не будут изменены.


1
Обратите внимание, что именование транзакций не только не нужно в MS SQL, но и может дать ложное ощущение контроля. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Yне работает, например. См stackoverflow.com/questions/1273376/...

0

В дополнение к потенциальным проблемам с блокировкой, которые вы можете вызвать, вы также обнаружите, что ваши журналы транзакций начинают расти, поскольку они не могут быть усечены после минимального LSN для активной транзакции, и если вы используете изоляцию моментальных снимков, ваше хранилище версий в tempdb будет расти за аналогичные причины.

Вы можете использовать dbcc opentranдля просмотра сведений о самой старой открытой транзакции.


0

Любая незавершенная транзакция оставит сервер заблокированным, и другие запросы не будут выполняться на сервере. Вам нужно либо откатить транзакцию, либо зафиксировать ее. Закрытие SSMS также приведет к прекращению транзакции, что позволит выполнять другие запросы.


-4

Поведение не определено, поэтому вы должны явно установить фиксацию или откат:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

«Если режим автоматической фиксации отключен, и вы закрываете соединение без явной фиксации или отката ваших последних изменений, то выполняется неявная операция COMMIT».

Hsqldb делает откат

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

результат

2011-11-14 14: 20: 22,519 основная ИНФОРМАЦИЯ [SqlAutoCommitExample: 55] [AutoCommit enabled = false] 2011-11-14 14: 20: 22,546 основная ИНФОРМАЦИЯ [SqlAutoCommitExample: 65] [Найдено 0 # пользователей в базе данных]


2
Это может быть верно для Oracle (я понятия не имею), но спрашивающий спрашивает о MS-SQL
PaulG

Первая цитата относится к драйверу JDBC, а не к серверу.
djechlin
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.