Подтвердить что ты не робот

Использование StatelessSession для пакетной обработки

Из документация

Если у нас есть случай, когда нам нужно вставить 1000 000 строк/объектов:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

Почему мы должны использовать этот подход? Какую пользу он приносит нам по сравнению с StatelessSession:

    StatelessSession session = sessionFactory.openStatelessSession();
    Transaction tx = session.beginTransaction();

    for ( int i=0; i<100000; i++ ) {
      Customer customer = new Customer(.....);
      session.insert(customer);
    }    

    tx.commit();
    session.close();

Я имею в виду, что этот ( "альтернативный" ) последний пример не использует память, не нужно синхронизировать, очищать из кэша, тогда это должно быть лучшей практикой для таких случаев? Зачем использовать предыдущий?

4b9b3361

Ответ 1

Из документации, на которую вы ссылаетесь:

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

Это некоторые существенные ограничения!

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

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

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

Ответ 2

Сессия без учета состояния имеет преимущество перед Сессией с точки зрения производительности, поскольку сеанс без сохранения не передаст транзакцию фиксации методам сеанса или сеанса, используемым в объекте Session. Тем не менее, важно отметить, что служба /DAO не должны пытаться выполнять манипуляции со сеансом в любом родительском или любом дочернем объекте. Это будет исключение. Кроме того, убедитесь, что вы закрыли сеанс явно, иначе в итоге будут пропущены соединения.

Чтобы добиться большей производительности с помощью сеанса без сохранения, если вы используете транзакцию Spring, пометьте транзакцию Spring как только чтение и установите необходимое распространение как НИКОГДА.

Но опять же, не пробуйте это, когда нужно манипулировать объектной моделью.

@Transactional(value="someTxnManager", readOnly=true, propagation=Propagation.NEVER)
    public List<T> get(...) {

        return daoSupport.get(...);
    }

в daoSupport

StatelessSession session = sessionFactory.openStatelessSession();
try{
// do all operations here
}
...
...
finally{
            session.close();
}

Ответ 3

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

и пакетная обработка происходит с использованием кешей
Простите меня, если я ошибаюсь.