springframework(十四)spring的事务管理

Spring提供了编程性事务管理与声明式的事务管理。Spring事务管理的抽象关键在于org.springframework.transaction.PlatformTransactionManager接口的实现。

PlatfromTransactionManager接口有许多具体的事务实现类,例如:DataSourceTransactionManagerHibernateTransactionManagerJdoTransactionManagerJtaTransactionManager等等。

  此处需要注意的是,要使用Mysql数据库进行事务处理,必须建立支持事务的表类型,例如:InnoDB的表类型。

1、  Spring提供的编程性事务

可以清楚的控制事务的边界,自行实现事务的开始时间,撤销时间,结束时间等,可以实现细粒度的事务控制。

编码例子如下:

   

    private PlatformTransactionManager txManager;

    public void setTxManager(PlatformTransactionManager txManager) {

       this.txManager = txManager;

}

    public void insertUser(User user)  {

       DefaultTransactionDefinition def = new DefaultTransactionDefinition();

       def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

       TransactionStatus status = txManager.getTransaction(def);

       try{

           JdbcTemplate tmp = new JdbcTemplate(dataSource);

           tmp.execute("insert  into tbl_user (name,pwd) values ('"+user.getName()+"','"+user.getPwd()+"')");

            //写错的sql,等着抛出运行时异常

           tmp.update("sssssssssssss");

           UserUpdate uu = new UserUpdate(dataSource);

            uu.update(new Object[]{user.getName(),user.getPwd()});

       }catch(DataAccessException e){

           txManager.rollback(status);

           throw e;

       }

           txManager.commit(status);

    }

配置文件的写法如下:

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

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

</bean>

<bean id="userDao" class="com.itcast.dao.impl.UserDaoImpl">

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

    <property name="txManager" ref="txManager"></property>

</bean>

 

2、  声明式的事务管理

Spring事务的相关API可以不用介入程序之中,只是在配置文件上修改配置下就可以移去事务管理服务。Spring的声明式事务是通过springAOP来实现的,所以执行程序的时候,请记得将spring-aop.jar给放到classpath中。

1)、最基础的事务配置如下:

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

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

</bean>

<bean id="userDao" class="com.itcast.dao.impl.UserDaoImpl">

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

    <property name="txManager" ref="txManager"></property>

</bean>

<!-- 事务代理 -->

<bean id="userDaoTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

    <property name="target" ref="userDao"></property>

    <property name="transactionManager" ref="txManager"></property>

    <property name="transactionAttributes">

    <props>

    <prop key="insert*">PROPAGATION_REQUIRED</prop>

</props>

我们在使用的时候只是需要取得userDaoTxProxy 而不是userDao就可以完成对这个Dao的事务控制了。

2)、将事务抽象提取,让我们的代理类取得一个拦截器方式的事务,从而将每个代理类的事务都抽象出来集中管理,这样只要我们命名规范,那么我们的事务处理就更加容易。

例如:

<!-- 将事务控制集中到一个bean -->

<bean id="transactionInteceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">

    <property name="transactionManager" ref="txManager"></property>

    <property name="transactionAttributeSource" >

     <value>com.itcast.dao.impl.UserDaoImpl.insert*=PROPAGATION_REQUIRED</value>

    </property>

</bean>

<bean id="userDaoTxProxy1" class="org.springframework.aop.framework.ProxyFactoryBean">

  <property name="target" ref="userDao"></property>

  <property name="interceptorNames">

    <list>

    <value>transactionInteceptor</value>

    </list>

  </property>

</bean>

 

注意这个beanclass实例式我们平时使用的代理daoProxyFactoryBean而不是上边的TransactionProxyFactoryBean实例,这样也就要求我们只能使用拦截器的方式将我们的事务切入到程序中。我们在调用userDao的时候,通过获取userDaoTxProxy1 就可以得到一个经过事务控制的bean了。

3、  事务属性的介绍

1)、传播行为:(7种)

  PROPAGATION_REQUIRED:支持现在的事务,如果没有就创建一个

  PROPAGATION_MANDATORY:必须在一个现存的事务中,否则就抛异常

  PROPAGATION_NEST:在一个嵌入的事务中进行,如果不是,则同PROPAGATION_REQUIRED

  PROPAGATION_NEVER:不应当在事务中进行,如果有就抛出异常

  PROPAGATION_NOT_SUPPORTED:不应当在事务中进行,如果有就暂停当前的事务

  PROPAGATION_REQUIRES_NEW:建立一个新的事务,如果现存一个事务就暂停它

  PROPAGATION_SUPPORTS:支持现在的事务,如果没有,就以非事务的方式执行。

2)、隔离层级

 可以让你根据实际的需求来对数据进行锁定设置。Spring提供的隔离层级的设置可以在TransactionDefinitionAPI文档说明上有。

3)、只读提示

  如果事务只进行读取的动作,则可以利用底层数据库在只读操作时发生的一些最佳化动作,由于这个动作利用到数据库的只读的事务操作最佳化,因此必须在事务中才有效。

4)、事务超期时间

  有的事务操作可能延续很长一段时间,事务本身可能关联到数据表格的锁定,因此长时间的事务操作会有效率上的问题。对于过长的事务操作,您要考虑Roll Back事务并要求重新操作,而不是无限时的等待事务完成。

4、  TransactionAttributeSourceTransactionAttribute

TransactionProxyFactoryBean上有setTransactionAttributeSource()与setTransactionAttribute的方法,他们是用来设置事务属性的策略实例

5、  Spring2.0的声明式事务管理:基于XML Schema

spring2.0中要设置声明式事务管理,可以依赖于spring2.0<aop><tx>标签,因而要记得加入相关的名称空间声明:

1)、给Bean标签增加相关的声明

<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns:aop="http://www.springframework.org/schema/aop"

 xmlns:tx="http://www.springframework.org/schema/tx"

 xsi:schemaLocation="http://www.springframework.org/schema/beans

 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

 http://www.springframework.org/schema/aop

 http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

 http://www.springframework.org/schema/tx

 http://www.springframework.org/schema/tx/spring-tx-2.0.xsd

 ">

2)、写配置文件

<!-- 使用spring2.0的标签来声明事务 -->

<tx:advice id="txAdvice" transaction-manager="txManager">

    <tx:attributes>

    <tx:method name="insert*" propagation="REQUIRED"/>

    <tx:method name="find*" read-only="true"/>

    </tx:attributes>

</tx:advice>

<aop:config>

  <aop:pointcut id="userDaoPointcut"

  expression="execution(* com.itcast.dao.IUserDao.*(..))"/>

  <aop:advisor advice-ref="txAdvice" pointcut-ref="userDaoPointcut"/>

</aop:config>

注意到<tx:method>中的属性设置,对于传播行为、隔离层级、只读、超时、异常时撤回或者提交,都有对应的“propagation”、“isolation”、“timeout”、“read-only”、“rollback-for”、“no-rollback-for”属性可以设置.若不设置,“propagation”的属性默认值为“REQUIRE”,“isolation”的默认值为“DEFAULT”,“timeout”的默认值为“-1(单位是秒)”、“read-only

的默认值是“false

  与先前介绍的spring2.0基于XML SchemalAOP设置相同,由于不再于设置文件中设置代理对象,所以直接取得“userDao”的实例进行操作就ok了。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值