首页 > 代码库 > Spring基于声明式的事务管理

Spring基于声明式的事务管理

事务管理

Spring提供了编码式和声明式事务管理的支持。

编码式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP)用助于用户将操作与事务解耦。

选择编码式还是声明式在很大程度上是在细粒度控制和易用性之间权衡。

 

 

Spring并不直接管理事务,而是提供多种事务管理器,将它们事务管理职责委托给JTA或其他持久化机制所提供的平台相关的事务实现。每个事务管理器都会充当某一特定平台的事务实现的门面,这使得用户在Spring中使用事务时,不用关注事务的实际实现是什么。

JDBC事务

<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

            <propertyname="dataSource"ref="dataSource"></property>

</bean>

Hibernate事务

         <beanid="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">

             <propertyname="sessionFactory"ref="sessionFactory"></property>

         </bean>

 

Spring对声明式的事务是通过AOP框架来完成。

声明式事务是通过事务属性来定义的,事务属性描述了事务策略如何应用到方法上,事务属性包括5个方面:传播行为、隔离级别、是否只读、事务超时、回滚规则。

传播行为:定义了客户端与被调用方法之间的事务边界。

 

隔离级别:一个事务可能受其它并发事务的影响程度。

     在并发事务中可能会出现脏读、不可重复度、幻读的数据操作问题,因此要求并发事务之间隔离。隔离级别:

  

 

 

是否只读:事务对后端的数据库进行只读操作,数据库可以利用事务的只读特性来进行一些特定的优化。

事务超时:如果一个事务执行的时间太长,就会导致占用资源,因此,我们通常设定一个事务超时时间,当超过这个时间,就会导致事务超时,那么事务就会回滚。

回滚规则:事务在默认时遇到运行时异常就会回滚,而检查时异常不会回滚。我们也可以设定在遇到特定检查时异常回滚来定义自己的回滚规则。

 

在XML中通过tx命名空间来定义事务通知

  <tx:adviceid="txAdvice">

               <tx:attributes>

                  <tx:methodname=""isolation="DEFAULT"/>

                  <tx:methodname=""no-rollback-for=""/>

                  <tx:methodname=""propagation="REQUIRED"/>

                  <tx:methodname=""read-only="false"/>

                  <tx:methodname=""timeout="-1"/>

               </tx:attributes>

  </tx:advice>

//name表示与事务属性相关联的方法

<tx:advice>声明一个事务,<tx:attributes>定义事务的属性

 

在我们声明事务的同时,还需要使用事务管理器:

<tx:adviceid="txAdvice" transaction-manager="transactionManager">  

………..

</tx:advice>

 

 

 到现在我们只是定义了事务通知,我们还应该声明哪些Bean应该被通知,因此我们就需要通过AOP切点来完成:

<aop:config>

             <aop:advisoradvice-ref="teAdvice"pointcut="exectution(*bean.User.*(..))"/>

          </aop:config>

 

到现在为止我们已经完全了解了声明式事务方法。

我们同样可以通过注解来简化我们的XML的事务,我们只需要在XML中使用:<tx:annotation-driven  transaction-manager="txManager"/>

 

然后在Bean上注解@Transactional,事务属性是通过注解的属性来完成,对于每一个@Transactional注解的Bean,<tx:annotation-driven/>会自动为其添加事务通知。

实例一:

<beanid="t" class="test.Test01"></bean>

 

    <bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 

      <propertyname="driverClassName"value="com.mysql.jdbc.Driver "> </property> 

      <propertyname="url"value="jdbc:mysql://localhost:3306/dataBase">  </property> 

      <propertyname="username"value="root"></property> 

      <propertyname="password"value=""></property> 

    </bean>

   

      <beanid="jdbcTemplate"class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">

        <constructor-argref="dataSource"></constructor-arg>

      </bean> 

<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

            <propertyname="dataSource"ref="dataSource"></property>

        </bean>

<tx:adviceid="txAdvice"transaction-manager="transactionManager">

               <tx:attributes>

                  <tx:methodname="*"propagation="SUPPORTS"/>

                  <tx:methodname=""read-only="false"/>

               </tx:attributes>

            </tx:advice>

       

          <aop:config>

             <aop:advisoradvice-ref="txAdvice"pointcut=" execution(**..Test01.update(..)) "/>

          </aop:config>

publicclass Test01 {

 

    public SimpleJdbcTemplategetSimpleJdbcTemplate() {

       

        ApplicationContext ac=newClassPathXmlApplicationContext("applicationContext.xml");

       

        SimpleJdbcTemplate  stj=ac.getBean("jdbcTemplate",SimpleJdbcTemplate.class);

       

        return stj;

    }

   

    publicintupdate(String sql)

    {

        returnthis.getSimpleJdbcTemplate().update(sql);

       

    }

   

    publicstatic voidmain(String[] args) {

       

        Test01 t=new Test01();

       

        SimpleJdbcTemplate  stj=t.getSimpleJdbcTemplate();

       

        String insertsql="insertinto users values(10,‘lisi‘,2)";

       

        introw=t.update(insertsql);

       

       System.out.println(row);}

}

 

 

实例二:

<beanid="t" class="test.Test01"></bean>

 

    <bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 

      <propertyname="driverClassName"value="com.mysql.jdbc.Driver "> </property> 

      <propertyname="url"value="jdbc:mysql://localhost:3306/dataBase">  </property> 

      <propertyname="username"value="root"></property> 

      <propertyname="password"value=""></property> 

    </bean>

   

      <beanid="jdbcTemplate"class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">

        <constructor-argref="dataSource"></constructor-arg>

      </bean> 

<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

            <propertyname="dataSource"ref="dataSource"></property>

        </bean>

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

        </beans>

 

   

    @Transactional(propagation=Propagation.SUPPORTS,readOnly=false)

    publicintupdate(String sql)

    {

        returnthis.getSimpleJdbcTemplate().update(sql);

       

    }

Spring基于声明式的事务管理