Ответ 1
все происходит в рамках транзакции. Иногда программное обеспечение автоматически управляет транзакцией для вас, но спящий режим - нет. будь то только для чтения или нет, в спящем режиме вы должны открывать и закрывать транзакции.
Я видел несколько примеров по интернету Hibernate, используя transaction.commit()
для выбранных операторов. Ниже приведен пример кода.
public static List<?> list(Class<?> className,int start,int limit,SearchFilter[] searchFilter){
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(className);
criteria.setFirstResult(start);
criteria.setMaxResults(limit);
for(SearchFilter sf : searchFilter){
String[] values = sf.getValue();
if(values != null){
if(values.length == 1) {
criteria.add(Restrictions.eq(sf.getField(), values[0]));
}else{
criteria.add(Restrictions.in(sf.getField(), values));
}
}
}
List<?> Objects = criteria.list();
transaction.commit();
return Objects;
}catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
}
return null;
}
Почему мы начинаем и совершаем транзакцию для оператора select?
все происходит в рамках транзакции. Иногда программное обеспечение автоматически управляет транзакцией для вас, но спящий режим - нет. будь то только для чтения или нет, в спящем режиме вы должны открывать и закрывать транзакции.
Я настоятельно рекомендую читать Доступ к транзакционным данным и режим автоматической фиксации. Позвольте мне процитировать небольшую часть:
(...)
Должно быть рассмотрено еще много вопросов когда вы вводите без трансакции доступ к данным в вашем приложении. Weve уже отметил, что введение нового тип транзакции, а именно только для чтения транзакций, может значительно усложнить любую будущую модификацию ваше приложение. То же самое верно, если вы вводите без трансакции операции.
Тогда у вас было бы три разных виды доступа к данным в вашем приложение: в обычных транзакциях, в транзакции только для чтения, и теперь также нетрансакционный, без гарантии. Представьте, что вы должны ввести операцию, которая записывает данных в единицу работы, которая была должен только читать данные. Представить что вы должны реорганизовать операции которые были непересекающимися транзакционный.
Наша рекомендация - не использовать режим автосохранения в приложении и применять только транзакции только для чтения когда есть очевидная производительность выгоды или при изменении будущего кода крайне маловероятны. Всегда предпочитайте регулярные транзакции ACID для группировки ваши операции доступа к данным, независимо от того, будете ли вы читать или записывать данные.
Сказав это, Hibernate и Java Стойкость позволяет без трансакции доступ к данным. Фактически, EJB 3.0 спецификация заставляет вас получить доступ если вы хотите реализовать атомный долговременный разговоры. Хорошо подойти к этому предмет в следующей главе. Теперь мы хотите немного углубиться в последствия режима автокоммутации в простое приложение для спящего режима. (Заметка что, несмотря на наши негативные замечания, есть некоторые хорошие варианты использования для автоматический режим. В нашем опыте autocommit часто используется для неправильные причины, и мы хотели стереть сначала очистите шифер.)
Работает без перехвата с гибернацией
Посмотрите на следующий код, который доступ к базе данных без границы транзакций:
Session session = sessionFactory.openSession(); session.get(Item.class, 123l); session.close();
По умолчанию в среде Java SE с конфигурацией JDBC, это что произойдет, если вы выполните это фрагмент кода:
- Открывается новый сеанс. Он не получает соединение с базой данных при этом пункт.
- Вызов метода get() запускает SQL SELECT. Сессия теперь получает JDBC Соединение из пула соединений. Спящий режим, по умолчанию, немедленно отключает режим автосохранения на этом соединение с setAutoCommit (false). Это эффективно запускает JDBC сделка!
- SELECT выполняется внутри этой транзакции JDBC. Сессия закрыто, и соединение возвращается в пул и выпущен Hibernate - Hibernate вызывает close() на JDBC Подключение. Что происходит с незафиксированная транзакция?
Ответ на этот вопрос: "Это зависит!" Спецификация JDBC ничего не говорит о ожидающем ответа транзакции при вызове функции close() связь. Что происходит, зависит от как поставщики реализуют Спецификация. С помощью Oracle JDBC драйверов, например, вызов close() совершает транзакцию! Наиболее другие поставщики JDBC используют разумный маршрут и откат любой ожидающей транзакции когда объект соединения JDBC закрыт, и ресурс возвращается бассейн.
Очевидно, что это не проблема для SELECT, вы выполнили (...)
Ну, коммит фактически бесполезен, но, как сказал psanton, все происходит в рамках транзакции.
Вам необходимо обернуть операции в транзакциях даже при выборе из-за уровней изоляции и повторяющихся чтений, возникающих при использовании MySQL InnoDB.
Посмотрите вопрос, с которым я столкнулся.
Коллекция Hibernate не обновляется, когда записи добавлены снаружи