JDBC - setAutoCommit для операции только для чтения - PullRequest
7 голосов
/ 25 сентября 2010

Допустим, у меня есть общий метод, который создает соединение с БД:

Connection getConnection() throws SQLException {
    Connection con = ... // create the connection
    con.setAutoCommit(false);
    return con;
}

Я поместил здесь вызов setAutoCommit(false), чтобы вызывающие его методы никогда не беспокоились о его настройке.Однако является ли это плохой практикой, если операция, выполняемая вызывающей стороной, только читает данные?Есть ли какие-либо дополнительные издержки?

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

Ответы [ 4 ]

5 голосов
/ 25 сентября 2010

Я поместил здесь вызов setAutoCommit (false), чтобы вызывающие его методы никогда не беспокоились о его настройке.

Это хорошая IMO, и я лично считаю, что никогда не следует включать режим автоматической фиксации внутри приложения.Поэтому я рекомендую отключить автоматическую фиксацию.

Однако является ли это плохой практикой, если операция, выполняемая вызывающей стороной, только читает данные?Есть ли какие-либо дополнительные издержки?

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

Кстати, на операторы SELECT влияет setAutoCommit(boolean) в соответствии с javadoc:

Устанавливает режим автоматической фиксации этого соединения в заданное состояние. Если соединение находится в режиме автоматической фиксации, все его операторы SQL будут выполняться и фиксироваться как отдельные транзакции .В противном случае его операторы SQL группируются в транзакции, которые завершаются вызовом метода commit или отката метода.По умолчанию новые подключения находятся в режиме автоматической фиксации.

Фиксация происходит после завершения инструкции. Время завершения инструкции зависит от типа инструкции SQL:

  • Для операторов DML, таких как операторы Insert, Update или Delete и DDL, оператор завершается сразу после завершения его выполнения.
  • Для операторов Select оператор завершенкогда связанный набор результатов закрыт.
  • Для объектов CallableStatement или для операторов, которые возвращают несколько результатов, оператор завершается, когда все связанные наборы результатов были закрыты, а все счетчики обновлений и выходные параметрыбыли найдены.
5 голосов
/ 25 сентября 2010

Autocommit не имеет значения для SELECT запросов.Но отключение автоматической фиксации действительно более распространенная практика.Более часто вы хотели бы запускать запросы в транзакции.Большинство пулов соединений также по умолчанию отключает его.Однако я бы предложил сделать его настройкой конфигурации вашего диспетчера соединений и / или перегрузить метод, принимая логический аргумент, чтобы вы по крайней мере имели любой контроль над ним для случая, который.

3 голосов
/ 18 июня 2015

Это старый вопрос, но я хотел дать другое мнение по этому вопросу.

Производительность

Снижение производительности от транзакций зависит от механизма управления параллелизмом: обычно многоуровневое управление параллелизмом или блокировка. Озабоченность, выраженная в других ответах, по-видимому, связана со стоимостью завершения транзакции, но, по моему опыту, самая большая проблема - это длительные транзакции, которые могут стать причиной узких мест в производительности. Например, если СУБД использует блокировку, некоторые части таблицы не могут быть обновлены, пока транзакция с этой таблицей не будет завершена. Еще большее разочарование в таких системах, как Oracle, заключается в том, что операции DDL (ALTER TABLE и т. Д.) Должны ждать, пока все транзакции, использующие эту таблицу, завершатся, что приведет к хлопотным тайм-аутам. Поэтому не думайте, что ваша транзакция не будет оштрафована, если вы просто используете SELECT s.

Условные обозначения

Тонкая проблема с отключением режима автоматической фиксации состоит в том, что вы переходите от значения по умолчанию, поэтому все, кто работает с вашим кодом, могут этого не ожидать. действительно легко оставить случайный путь через функцию, который не заканчивается явным commit или rollback, и это может привести к непредсказуемому поведению в последующих вызываемых функциях. И наоборот, большая часть кода взаимодействия с БД, который я видел, содержит один оператор в каждой функции, для которого очень хорошо подходит поведение автоматической фиксации. Фактически, многие функции с несколькими утверждениями, с которыми я сталкивался, могли быть переписаны как отдельные операторы с немного большим ноу-хау в SQL - к сожалению, плохое приближение к объединениям, реализованным в Java, встречается довольно часто.

Мои личные предпочтения, основанные на разумном опыте, следующие для любых функций, выполняющих вызовы в базу данных:

  • придерживаться стандартного поведения JDBC при автоматической фиксации;
  • когда ваша функция включает в себя более одного оператора SQL, используйте явную транзакцию, задав setAutocommit(false) в начале каждой функции и вызвав commit() (или rollback(), если необходимо) в конце, а в идеале rollback() в блоке catch;
  • принудительно применяет значение по умолчанию, помещая setAutocommit(true) в блок finally, который упаковывает ваши вызовы JDBC в функцию (в отличие от таких API, как PHP / PDO, JDBC не сделает этого за вас после commit() / rollback() );
  • , если вы чувствуете дополнительную защиту, явно установите ваш выбор setAutocommit(true) или setAutocommit(false) в начале каждой функции;
1 голос
/ 25 сентября 2010

Я бы никогда не установил для autoCommit значение true в любом месте приложения. Снижение производительности, если вообще что-то - ничто по сравнению со стороной эффекты соединения autocommit=true.

Вы говорите, что никогда не будете использовать это соединение для DML. Но это намерение , поддерживаемое, возможно, стандартами кодирования и т. Д. Но на практике возможно использовать это соединение для операторов DML. Это достаточная причина для меня, чтобы никогда не включать автоматическую фиксацию.

Select операторам определенно потребуется немного памяти / ЦП / сети. Пусть накладные расходы autocommit будут (очень незначительными) фиксированными накладными расходами для каждого оператора select, чтобы обеспечить целостность данных и стабильность вашего приложения.

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