Выбрать спящий режим

Я видел несколько примеров по интернету 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?

Ответы

Ответ 2

Я настоятельно рекомендую читать Доступ к транзакционным данным и режим автоматической фиксации. Позвольте мне процитировать небольшую часть:

(...)

Должно быть рассмотрено еще много вопросов когда вы вводите без трансакции доступ к данным в вашем приложении. 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, вы выполнили (...)

Ответ 3

Ну, коммит фактически бесполезен, но, как сказал psanton, все происходит в рамках транзакции.