2013-11-16 2 views
1

Я получил это веб-приложение Java, которое использует Struts и Hibernate. В самом верхнем слое содержатся классы действия Struts. Тогда есть классы бизнес-логики, которые отвечают за логику приложения. Наконец, существует слой DAO (называемый мостом базы данных), который отвечает за связь с базой данных.Hibernate - Где лучше всего начать транзакцию в многоуровневом веб-приложении?

В настоящее время я открытые сессии и делать операции в DAO слое, как это:

public static void saveObject(Object object) throws Exception { 
     Session session = null; 

     try { 
      session = HibernateUtil.getSessionFactory().getCurrentSession(); 
      session.beginTransaction(); 
      session.save(object); 

      session.getTransaction().commit(); 

     } catch (Exception e) { 
      session.getTransaction().rollback(); 
      e.printStackTrace(); 
      throw e; 
     } finally { 
      if (session != null) 
       if (session.isOpen()) 
        session.getTransaction().rollback(); 
     } 
    } 

Там, кажется, некоторые проблемы с этим подходом:

1) Логически мои транзакции были мои Struts действия (контроллеры), который должен быть зафиксирован или откат. Действие Struts может привести к более чем одному вызову DAO, поэтому возможно, что некоторые части логической транзакции будут зафиксированы, а остальная часть будет откат, что повредит целостность данных.

2) Некоторые объекты содержат несколько ленивых коллекций. Если мы выполняем транзакции на уровне DAO, нам необходимо инициализировать те коллекции, которые не являются эффективным способом. потому что нам не нужно загружать коллекции в каждое действие. Поэтому, когда действие требует ленивой коллекции, нам нужно открыть сеанс в действии и загрузить там ленивую коллекцию, которая является грязным решением.

Я думаю, что лучше избегать транзакций в слое DAO. Если мы разместим транзакции в действии Struts, они будут обрабатываться как атомарные транзакции, и согласованность данных будет сохранена. с другой стороны, когда нам нужна ленивая коллекция, мы можем ее инициализировать внутри действия.

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

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

+0

Вы должны действительно узнать об инъекциях зависимостей и декларативных транзакциях вместо того, чтобы управлять ими самостоятельно, программно. Используйте Spring (http://struts.apache.org/release/2.2.x/docs/spring-and-struts-2.html), демаркируйте транзакции декларативно на уровне службы и, возможно, используйте Spring open session in view filter чтобы избежать проблем с ленивой загрузкой. Ваш код будет значительно сокращаться, быть более читаемым и проверяемым, а также быть более прочным. –

+0

Если приложение устарело *, возможно, ему нужно * REST * ^^ –

ответ

1

Кажется, вы думаете в правильном направлении, но вы должны иметь в виду, что сеансы в Hibernate не зависят от транзакций. Посмотрите на transaction strategy configuration, который может применяться к вашему приложению.

Затем вы должны прочитать эту статью, как работают sessions and transactions. В последнее время вы можете следовать подходу Generic DAO, не знаете почему, но эта техника очень популярна.

И, наконец, все вышеперечисленное уже реализовано сеткой Struts2 jQuery. Посмотрите на this ответ.

Кажется, что все вышеперечисленные независимы от Spring, если вам нравится, когда Spring управляет транзакциями, тогда вы должны пойти here.

+0

https://community.jboss.org/wiki/SessionsAndTransactions получил мои ответы, теперь я использую шаблон сеанса для каждого запроса. –

Смежные вопросы