«Сделка в поле зрения» с Hibernate, Spring, Struts - PullRequest
3 голосов
/ 21 января 2011

Из справочного руководства Hibernate: «Используйте одну транзакцию базы данных для обслуживания запроса клиентов, запуска и принятия его при открытии и закрытии сеанса»

Spring поддерживает этот шаблон? Я использую поддержку транзакций Spring с аннотацией @Transactional и шаблоном «Открыть сеанс» (org.springframework.orm.hibernate3.support.OpenSessionInViewFilter), но транзакции должны быть ограничены методами обслуживания, поэтому я получаю несколько транзакций за просмотр, а не только один.

Ответы [ 3 ]

1 голос
/ 21 января 2011

Вы, вероятно, не хотите использовать функциональность Transaction in View. Обычно то, что происходит по запросу, составляет

  1. запрос приходит
  2. вызывает некоторую операцию, которая сохраняет данные в базу данных
  3. ответ гаснет. то есть визуализировать страницу успеха или вернуть json или что-то еще

Причина, по которой вы не хотите видеть «транзакцию в поле зрения», заключается в том, что при возникновении ошибки на шаге 3 ваша транзакция будет откатываться, даже если фактическая бизнес-логика была успешной, только рендеринг ответа не удался.

Теперь я сделал предположение, что вы хотите, чтобы данные были зафиксированы, даже если после фиксации произошла ошибка. Если это предположение неверно, тогда все в порядке.

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

Service1.op1()
Service2.op2()

и вы вызываете оба этих метода для одного запроса. Вы можете просто создать другой сервис

AppFacade.doOp1andOp2()

, который вызывает op1 и op2 для соответствующих служб.

Другой возможностью было бы настроить Spring для размещения транзакций вокруг ваших действий Struts с декларативным управлением транзакциями. Обратите внимание, что с транзакциями с момента открытия tx до момента его закрытия все операции с БД будут использовать одну и ту же транзакцию, поэтому даже если вы вызываете несколько сервисов, все они используют один и тот же tx. =. Смотрите документацию здесь: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

конкретно 10.5.2

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

0 голосов
/ 12 августа 2011

Объявите класс, который реализует OpenSessionInViewFilter / Interceptor Hibernate ..... Пример приведен ниже ...

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;

public class CustomHibernateSessionViewFilter extends   OpenSessionInViewFilter {

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
    Session session = super.getSession(sessionFactory);
    session.setFlushMode(FlushMode.COMMIT);
    return session;
}

protected void closeSession(Session session, SessionFactory factory) {
    session.flush();
    super.closeSession(session, factory);
}

}

В web.xml (или контексте приложения): -

<filter>
    <filter-name>OSIVF Filter</filter-name>
    <filter-class>your.path.to.CustomHibernateSessionViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>OSIVF Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Надеюсь, это решит вашу проблему. Пожалуйста, дайте мне знать, сработало ли это.

0 голосов
/ 21 января 2011

Когда вы используете шаблон «Открыть сеанс в представлении» (org.springframework.orm.hibernate3.support.OpenSessionInViewFilter), чтобы включить, например, ленивую загрузку в вашем рендеринге http (например, JSP), и смешать его с управлением транзакциями с помощью @Transactional в вашем методе обслуживания, тогда это кажется мне подходом наилучшей практики.

Причина, по которой я так думаю:

  • Если вам нужна ленивая загрузка в JSP, то практическое требование - «Открыть сеанс в поле зрения».
  • Контроль транзакций принадлежит вашей бизнес-логике, поэтому он не может (на самом деле) выполняться фильтром.

Так что, по крайней мере, вам нужны оба.

...