JDBC commit (): что происходит за кулисами? - PullRequest
2 голосов
/ 09 марта 2011

Я помогаю с тупиковой охотой. Среда: Tomcat 5.5, Java 5, Microsoft SQL Server 2008, jTDS (замена старого драйвера). У нас есть устаревший пул соединений.

Код базы данных всегда следует этой схеме:

connection = connectionPool.getConnection(); // 1
boolean previousAutoCommitStatus = connection.getAutoCommit(); // 2
connection.setAutoCommit(false); // 3

// ... use the connection ...
// execute prepared statement 4
// execute prepared statement 5
// execute prepared statement 6

connection.commit(); // 7
connection.setAutoCommit(previousAutoCommitStatus); // 8
connectionPool.releaseConnection(connection); // 9

Пока мы охотились за ошибкой (простите: программный дефект), мне было интересно: как работает драйвер? Мое предположение: все, что я делаю между (3) и (7), ставится в очередь драйвером / СУБД. Только когда я connection.commit() СУБД начинает новую транзакцию, получает каждую блокировку, необходимую для операций (я надеюсь, что она достаточно умна, чтобы блокировать меньший возможный набор объектов), выполняет операторы и снимает блокировку, закрывая транзакцию.

Или, как только я выполню подготовленный оператор, СУБД блокирует таблицу?

РЕДАКТИРОВАТЬ : что я хочу понять, так это, если «commit ()» преобразуется в набор операторов SQL, начинающихся с «начать таблицу транс / блокировки» и заканчивающихся «таблица фиксации / разблокировки» или если любая Java executeStatement() немедленно получает блокировку.

ТИА

Ответы [ 4 ]

5 голосов
/ 15 марта 2011

Если вы заинтересованы в деталях, На connection.commit реализации JSBC SQLServer

Следующая команда выдана

IF @@TRANCOUNT > 0 COMMIT TRAN

@@ TRANCOUNT = 0 - нет открытой транзакции @@ TRANCOUNT = 1 - 1 открытая транзакция @@ TRANCOUNT = 10 - 10 открытых транзакций

Если для параметра autocommit установлено значение false,

set implicit_transactions on

Это команды MS SQLServer.

1 голос
/ 14 марта 2011
connection.setAutoCommit(false); 

Инициирует «BEGIN TRAN» на сервере БД и

connection.commit();

Инициирует «COMMIT TRAN»

Если вы хотите предотвратить блокировки между этими двумя операторами, установите изоляцию соединенияУровень «Чтение без связи».Вы должны будете убедиться, что это приемлемо в этом сценарии.

setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
1 голос
/ 09 марта 2011

Согласно этому ресурсу транзакция начинается, как только вы позвоните setAutocommit(false);

Я думаю, что она все еще зависит от драйвера, но это будет типично.См. Также MSDN , в котором говорится то же самое.

//Switch to manual transaction mode by setting
//autocommit to false. Note that this starts the first 
//manual transaction.
con.setAutoCommit(false);
0 голосов
/ 14 марта 2011

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

setAutoCommit (false) не обязательно начинает транзакцию в базе данных, и операторы не обязательно выполняются в базе данных или даже получают блокировки, когда вы вызываете функцию execute в вашем коде, как вы и предполагали. При этом, насколько я знаю, разделяемые (читаемые) блокировки обычно получаются при выполнении оператора; обновление блокирует, когда вызывается commit. Возможно, вы попали в тупик преобразования (что происходит, когда блокировки чтения нескольких операторов для данного объекта ожидают преобразования в блокировки записи), я бы проверил, есть ли в ваших операторах обновления вложенные выборки, которые могут привести к такой блокировке.

...