Зачем мне нужна транзакция в Hibernate для операций только для чтения?
Блокирует ли БД следующая транзакция?
Пример кода для получения из БД:
Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here
tx.commit() // why tx.commit? I don't want to write anything
Могу я использовать session.close()
вместо tx.commit()
?
java
database
hibernate
transactions
database-connection
user93796
источник
источник
Ответы:
На самом деле у вас могут быть причины отмечать транзакции как доступные только для чтения.
autocommit=true
если другой параметр не был установлен явно.@Transactional(readonly=true)
, Spring установит транзакцию JDBC в режим только для чтения, таким образом, вы будете определять, действительно ли возможна запись в БД в рамках этой транзакции. Если ваша архитектура громоздка и некоторые члены команды могут решить поместить запрос на изменение там, где он не ожидается, этот флаг укажет вам на проблемное место.Подводя итог - можно пойти обоими путями, но нужно понимать последствия.
источник
Все операторы базы данных выполняются в контексте физической транзакции, даже если мы явно не объявляем границы транзакции (BEGIN / COMMIT / ROLLBACK).
Если вы не объявляете границы транзакции явно, тогда каждый оператор должен будет выполняться в отдельной транзакции (
autocommit
режиме). Это может даже привести к открытию и закрытию одного соединения для каждого оператора, если ваша среда не может иметь дело с привязкой соединения к потоку.Объявление службы as
@Transactional
даст вам одно соединение на весь период транзакции, и все операторы будут использовать это одно изолированное соединение. Это лучше, чем вообще не использовать явные транзакции.В больших приложениях у вас может быть много одновременных запросов, и уменьшение количества запросов на получение соединения с базой данных определенно улучшит общую производительность вашего приложения.
JPA не применяет транзакции к операциям чтения. Только записи в конечном итоге вызывают исключение, необходимое для транзакции, если вы забыли запустить транзакционный контекст. Тем не менее, всегда лучше объявлять границы транзакций даже для транзакций только для чтения (в Spring
@Transactional
позволяет помечать транзакции только для чтения, что дает большое преимущество в производительности).источник
Транзакции действительно блокируют базу данных - хорошие движки базы данных разумно обрабатывают параллельные блокировки - и полезны при использовании только для чтения, чтобы гарантировать, что никакая другая транзакция не добавляет данные, которые делают ваше представление несогласованным. Вы всегда хотите транзакцию (хотя иногда разумно настроить уровень изоляции, лучше не делать этого для начала); если вы никогда не пишете в БД во время транзакции, и фиксация, и откат транзакции будут одинаковыми (и очень дешевыми).
Теперь, если вам повезло и ваши запросы к БД таковы, что ORM всегда сопоставляет их с отдельными SQL-запросами, вы можете обойтись без явных транзакций, полагаясь на встроенное в БД поведение автофиксации, но ORM - относительно сложные системы. так что совершенно небезопасно полагаться на такое поведение, если только вы не проведете гораздо больше работы, проверяя, что на самом деле делает реализация. Написание явных границ транзакций намного проще сделать правильно (особенно если вы можете сделать это с помощью AOP или какой-либо подобной техники, основанной на ORM; я полагаю, что с Java 7 и далее можно использовать try-with-resources).
источник
Не имеет значения, только читаете вы или нет - база данных должна по-прежнему отслеживать ваш набор результатов, потому что другие клиенты базы данных могут захотеть записать данные, которые могут изменить ваш набор результатов.
Я видел ошибочные программы, убивающие огромные системы баз данных, потому что они просто читают данные, но никогда не фиксируют, заставляя журнал транзакций расти, потому что БД не может освободить данные транзакции до COMMIT или ROLLBACK, даже если клиент ничего не сделал часами.
источник