【问题标题】:Spring Hibernate transaction managementSpring Hibernate 事务管理
【发布时间】:2012-10-16 18:40:41
【问题描述】:

我刚刚开始使用 spring 和 hibernate 制作一个项目。我的 DAO 层类扩展了 HibernateDaoSupport。我们没有使用注释。 之前,我们使用的是 struts,因此我们使用了 Session 类提供的 getTransaction、commit、rollback .. 方法。 我的要求很简单,对于所有的DAO类,如果有异常就回滚,否则提交。请提出一种引入spring事务管理的最简单方法。

【问题讨论】:

    标签: spring hibernate transactions


    【解决方案1】:

    您的问题中有些事情不清楚。我的解释基于以下假设 -

    • 您正在使用 spring 创建数据源和会话工厂
    • 您使用的是 Java 5 或更高版本,并且可以使用注解。

    这是您的弹簧配置的样子。

        <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:hsql://localhost:9001" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>
    
    <bean id="mySessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="mappingResources">
            <list>
                <value>product.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.HSQLDialect
            </value>
        </property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory" />
    </bean> 
    
    <tx:annotation-driven transaction-manager="transactionManager"  />
    

    设置完成后,您可以在 DAO 方法上使用 spring 事务注释,如下所示。 Spring 将负责启动事务、提交事务或在抛出异常时回滚事务。如果您有业务服务,最好在您的服务上使用事务注释而不是 DAO。

    @Transactional(propagation=Propagation.REQUIRED)
    public class MyTestDao extends HibernateDaoSupport {    
    public void saveEntity(Entity entity){
        getHibernateTemplate().save(entity);
    }
    @Transactional(readOnly=true)
    public Entity getEntity(Integer id){
        return getHibernateTemplate().get(Entity.class, id);
    }
     }
    

    下面的代码展示了如何使用 spring 对 AOP 的支持而不是注解来实现事务管理。

        <!-- Define your 'myDatasource' bean and 'mySessionFactory' bean as shown in previous code snippet -->
    <!--  Then follow the steps shown below -->
    
    <bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory" />   
    
    <!-- this is the dao object that we want to make transactional -->
    <bean id="testDao" class="com.xyz.daos.MyTestDao" />
    
    <!-- the transactional advice  -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- all methods starting with 'get' are read-only -->
            <tx:method name="get*" read-only="true" />
            <!-- other methods use the default transaction settings (see below) -->
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    
    <!-- ensure that the above transactional advice runs for any execution of 
        a method in 'daos' package-->
    <aop:config>
        <aop:pointcut id="allDaoMethods"
            expression="execution(* com.xyz.daos.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethods" />
    </aop:config>
    

    更多详情,请参阅 - Spring Declarative Transactions

    【讨论】:

    • 非常感谢您提供清晰准确的答案。此示例是使用注释的快速演示。但在这里我注释了每一种方法。我的所有课程都需要通用行为。是否可以在 xml 中定义它,比如说......
    • 我猜注释是唯一的出路。为我的要求实现了相同的功能。
    • 您确实可以使用 Spring aop 获得所需的行为。如果您决定使用注释,需要注意的是您不必为每个方法添加注释。您可以只注释您的类,所有方法都继承该行为,您可以注释一个方法来覆盖该行为。
    猜你喜欢
    • 2016-12-02
    • 1970-01-01
    • 2012-05-06
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多