1

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

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

4

1 回答 1

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(),因为它已经提交。

于 2015-04-28T03:59:01.170 回答