Spring HibernateDaoSupport创建多个会话

时间:2015-04-27 17:38:52

标签: java spring hibernate spring-transactions spring-orm

我正在为我的Web应用程序使用Struts2.3 + Spring 3.2.6 + Hibernate 3.X。

我正在使用注释来管理交易。 我的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,我将失去Spring的事务管理),而不会丢失Spring事务管理。

1 个答案:

答案 0 :(得分:1)

如果您正在使用Hibernate,请使用DAO类来扩展HibernateDaoSupport。现在,您可以从getHibernateTemplate()方法获取会话。这样你就可以通过spring-hibernate管理会话

你可以试试这个 -

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>

删除 -

<tx:annotation-driven transaction-manager="transactionManager" />
来自appcontext.xml

现在AOP应该管理交易。

交易如何运作 - 假设您在多个DAO方法中持久化对象并且希望它们都在一个事务中发生,那么您必须在调用DAO方法的服务层方法中应用事务。例如,在我的例子中,服务层是com.test.customer.bo.Custom。*

如果你没有这样做,那么你的每个DAO方法都将在一个单独的事务中执行,如果没有异常发生,它将被持久化到数据库。如果在DAO层的method2()中发生异常,它将不会回滚方法1(),因为它已经提交。