2015-04-27 7 views
1

Я использую Struts2.3 + Spring 3.2.6 + Hibernate 3.X для своего веб-приложения.Spring HibernateDaoSupport создает несколько сеансов

Я использую аннотации для управления транзакцией. Мой класс DAO приведен ниже.

@Transactional(readOnly = true, rollbackFor={Exception.class}) 
public class CustomerDAOImpl extends HibernateDaoSupport implements CustomerDAO{ 

    //adds the customer 
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor = {Exception.class}) 
    public void addCustomer(Customer customer){ 
     Session session = getSession(); 
     System.out.println("M1() Hash Code: --->"+session.hashCode()+ " Thread id: "+Thread.currentThread().getId()); 
     //session.save(customer); 
    } 

    //return all the customers in list 
    // @Transactional(propagation=Propagation.REQUIRED, rollbackFor = {Exception.class}) 
    @Transactional(readOnly = true) 
    public List<Customer> listCustomer(){ 
     Session session = getSession(); 
     System.out.println("M2() Hash Code: --->"+session.hashCode()+ " Thread id: "+Thread.currentThread().getId()); 
     return null; //logic to get the list based on condition 

    } 

Эти методы будут вызываться из уровня обслуживания, и это похоже на нижеследующее;

customerDAO.addCustomer(customer); 
customerDAO.listCustomer(); 

Я получаю различных сессий для того же потока когда приведенный выше код выполняется.

Выход:

M1() Hash Code: --->5026724 Thread id: 21 
M2() Hash Code: --->8899550 Thread id: 21 

В связи с этим, если любое исключение приходит в method2() данные, которые сохранялись с помощью method1() не откатить.

Пожалуйста, дайте мне знать, как получить одиночную сессию на основе потока (если я поеду на свой собственный HibernateFactory, я потеряю управление транзакциями к весне), не потеряв управление весенними транзакциями.

ответ

1

Если вы используете Hibernate, сделайте свой класс DAO для расширения HibernateDaoSupport. Теперь вы можете получить сеанс из метода getHibernateTemplate(). Таким образом, вы можете иметь сеанс под управлением весенне-зимуют

Вы можете попробовать это -

appContext.xml

<tx:advice id="txAdvice" transaction-manager="transactionManager"> 
     <tx:attributes> 
     <tx:method name="submit*" propagation="REQUIRED" read-only="false" rollback-for="Exception"/> 
</tx:attributes> 
    </tx:advice> 
    <aop:config> 
     <aop:pointcut id="appControllerTransactionPointCuts" 
      expression="execution(* com.test.customer.bo.Custom.*(..))" /> 
<aop:advisor advice-ref="txAdvice" pointcut-ref="appControllerTransactionPointCuts" /> 
    </aop:config> 

Remove -

<tx:annotation-driven transaction-manager="transactionManager" /> 

из appcontext.xml

Теперь АОП должен управлять транзакциями.

Как работает транзакция - Предположим, что вы сохраняете объекты в нескольких методах DAO, и вы хотите, чтобы все они произошли в одной транзакции, тогда вы должны применить транзакцию в методе уровня обслуживания, где вызываются методы DAO. Например, в моем случае сервисный уровень - com.test.customer.bo.Custom. *

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

+0

Также добавьте tx: annotationdriven в свой весенний контекст приложения, чтобы весна управляла транзакцией – Waqar

+0

Я пробовал. но все же транзакция не откат. – Daya

+0

Вы добавили или , так как вы также используете AOP – Waqar

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