ручная фиксация с атрибутом @Transactional - PullRequest
3 голосов
/ 12 марта 2012

Я использую шаблон Spring + Hibernate для обработки сущностей.За один раз загружается достаточно большое количество сущностей, поэтому я извлекаю итератор из шаблона гибернации.

Каждая сущность должна обрабатываться как единая единица работы.Я попытался поместить обработку объекта в отдельную транзакцию (распространение = REQUIRED_NEW).Однако я закончил с исключением, заявив, что прокси ограничен двумя сессиями.Это связано с приостановкой транзакции, используемой для отложенной загрузки итератора.Я использую один и тот же компонент для отложенной загрузки и обработки объектов.(Может быть, его следует реорганизовать в два отдельных dao: один для отложенной загрузки и один для обработки?)

Затем я попытался использовать одну транзакцию, которая фиксируется после обработки каждой сущности.Намного лучше, здесь нет исключений во время обработки сущностей, но после того, как обработка завершена и метод возвращается, исключение выдается из кода управления весенними транзакциями.

@Transactional
public void processManyManyEntities() {
    org.hibernate.Sesstion hibernateSession = myDao.getHibernateTemplate().getSessionFactory().getCurrentSession();
    Iterator<Entity> entities = myDao.findEntitesForProcessing();
    while (entities.hasNext()) {
        Entity entity = entities.next();
        hibernateSession.beginTransaction();
        anotherBean.processSingleEntity(entity);
        hibernateSession.getTransaction().commit();
    }
}

processSingleEntity - это метод в другом компоненте, аннотированный@Transactional, поэтому существует одна транзакция для всех сущностей.Я проверил, какая транзакция вызывает исключение: это самая первая транзакция, возвращенная из hibernateSession.beginTransaction(), поэтому она просто не обновляется в диспетчере транзакций.

Есть несколько вопросов:

isМожно ли избежать исключения привязки сеанса без рефакторинга dao? , что не является актуальным вопросом, поскольку проблема связана с Session и hibernate, а не с dao

Возможно ли обновить транзакцию в диспетчере транзакций? решено

можно ли использовать ту же транзакцию (для anotherBean.processSingleEntity(entity);) без @Transactional аннотации к processManyManyEntities?

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Возможность обновления транзакции в диспетчере транзакций.Все, что вам нужно сделать, это получить экземпляр SessionHolder из TransactionSynchronizationManager.getResource(sessionFactory) и установить транзакцию в держателе сеанса на текущую.Это позволяет фиксировать транзакцию всякий раз, когда это необходимо, и позволяет транзакции быть зафиксированной менеджером транзакций Spring после возврата метода.

1 голос
/ 12 марта 2012

Я бы предпочел удалить аннотацию @Transactional для "processManyManyEntities ()" и быстро загрузить все данные из "findEntitesForProcessing".

Если вы хотите, чтобы каждая сущность данных была транзакционной в "processSingleEntity", то @Transactinoal для "processSingleEntity" подойдет. Вам не нужно аннотировать @Transactional для "processManyManyEntities ()". Но в случае отложенной загрузки активная загрузка является необходимым средством предотвращения загрузки исходных данных в другом сеансе, скажем, в «processSingleEntity».

Поскольку транзакция для каждой сущности данных, транзакционная граница при загрузке исходных данных не относится к вашей транзакции. Не позволяйте "ленивой загрузке" усложнять ваше намерение транзакции для модификации данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...