【问题标题】:Spring HibernateDaoSupport creates multiple sessionsSpring HibernateDaoSupport 创建多个会话
【发布时间】:2015-04-27 17:38:51
【问题描述】:

我正在为我的 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() 持久化的数据不会回滚

请告诉我,如何在不丢失 Spring 事务管理的情况下获得基于线程的单个会话(如果我使用自己的 HibernateFactory,我会失去 Spring 的事务管理)。

【问题讨论】:

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


    【解决方案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()发生异常,不会回滚method1(),因为它已经提交了。

    【讨论】:

    • 同时在你的 spring 应用上下文中添加 tx:annotationdriven 以便 spring 管理事务
    • 我试过了。但事务仍然没有回滚。
    • 你是否添加了 因为你也在使用 AOP
    • 试试这个 - 只用 xml,没有注释 这对我有用
    • 我想我有你的问题。您正在 DAO 层应用事务。因此,您的方法 M1() 在 1 个事务中执行,而您的方法 M2() 在另一个事务中执行。如果您希望 DAO 层的方法 M1() 和 M2() 在 1 个事务中执行,则应删除 DAO 层的注释并将其放在服务层的调用方法上(与服务层的方法相同)调用 DAO 层的 M1() 和 M2()。
    猜你喜欢
    • 2013-09-11
    • 2011-03-14
    • 2015-06-13
    • 2015-05-04
    • 1970-01-01
    • 2014-03-17
    • 2016-01-18
    • 2019-03-03
    • 2014-09-17
    相关资源
    最近更新 更多