Использование 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();
Я имею в виду, что этот ( "альтернативный" ) последний пример не использует память, не нужно синхронизировать, очищать из кэша, тогда это должно быть лучшей практикой для таких случаев? Зачем использовать предыдущий?
Ответы
Ответ 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
• кеш первого уровня
• взаимодействие с любым кешем второго уровня или кешем запросов
• транзакционная запись или автоматическая грязная проверка
и пакетная обработка происходит с использованием кешей
Простите меня, если я ошибаюсь.