#hibernate #spring
#режим гибернации #spring
Вопрос:
Изначально код имел следующую структуру, и он работал отлично —
Начальный код:
@Transactional
class foo
{
void public work()
{
task1;
task2;
}
}
Поскольку две задачи могли выполняться параллельно, мы провели рефакторинг, чтобы распределить их по двум потокам.
Написал две задачи в разных потоках, вызвал их параллельно и получаю следующую ошибку при вызове соответствующего DAO
Сеанс гибернации не привязан к потоку, а конфигурация не позволяет создавать здесь нетранзакционный сеанс
Поскольку сеанс гибернации привязан к текущему потоку, это становится проблемой с дочерними потоками.
Переработанный код:
@Transactional
class foo
{
void public work()
{
final Thread t1 = new Thread(new Job1());
t1.start();
final Thread t2 = new Thread(new Job2());
t2.start();
t1.join();
t2.join();
}
class Job1
{
public void run()
{
task1;
}
}
class Job2
{
public void run()
{
task1;
}
}
}
Ответ №1:
Даже если возможно разделить транзакцию, управляемую Spring, между несколькими потоками, это не очень хорошая идея, поскольку транзакции в режиме гибернации привязаны к Session
s, а режим гибернации Session
не потокобезопасен, поэтому вы не можете использовать одну и ту же транзакцию Session
из нескольких потоков.
Возможно, было бы лучше спроектировать ваш код таким образом, чтобы все обращения к базе данных выполнялись одним потоком, а другие потоки выполняли только обработку данных.