spring的jdbc事务管理2

1.  spring提供编程式的事务管理与声明式的事务管理:

编程式事务管理:可以清楚的控制事务的边界,可以由我们自行实现事务的开始时间、撤销操作的时机、结束时间,可以实现细粒度的事务控制。

声明式事务管理,大多数情况下不需要细粒度的控制,而采取声明式的事务管理,好处是spring事务管理的相关API可以不用介入程序中,可以自由的插拔(通过配置实现)

Spring的jdbc编程事务管理:

   Spring提供了两种方式实现编程式的事务管理,一是直接使用platformTransactionManager的实现,二是使用org.springframework.transaction.support.TransactionTemplate。

前者的使用这里举例是其实现类:DataSourceTransactionManager,之前的springjdbc的项目中需要修改下DaoServiceImpl:

package com.springframework.sample.jdbc.dao;

 

import java.util.ArrayList;

import java.util.List;

import javax.sql.DataSource;

importorg.springframework.dao.DataAccessException;

importorg.springframework.jdbc.core.JdbcTemplate;

importorg.springframework.jdbc.datasource.DataSourceTransactionManager;

importorg.springframework.transaction.TransactionDefinition;

importorg.springframework.transaction.TransactionStatus;

importorg.springframework.transaction.support.DefaultTransactionDefinition;

importcom.springframework.sample.jdbc.pojo.Banzu;

importcom.springframework.sample.jdbc.pojo.BanzuRowMapper;

 

public class DaoServiceImplimplements DaoInterface {

   privateJdbcTemplate jdbcTemplate;

   //privateDataSource dataSource;

   //加入spring的编程式的事务管理

   privateDataSourceTransactionManager transactionManager;

   privateDefaultTransactionDefinition def;

  

   publicJdbcTemplate getJdbcTemplate() {

      returnjdbcTemplate;

   }

 

   publicvoid setJdbcTemplate(JdbcTemplate jdbcTemplate) {

      this.jdbcTemplate= jdbcTemplate;

   }

   publicvoid setDataSource(DataSource dataSource){

      this.jdbcTemplate= new JdbcTemplate(dataSource);

      transactionManager= new DataSourceTransactionManager(dataSource);

      //建立事务定义,明确传输行为为:支持当前事务,如果当前没有则新建

      def= new DefaultTransactionDefinition();

      def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

   }

 

   @Override

   publicvoid saveBanzu(Banzu banzu) {

      //TODO Auto-generated method stub

      Stringsql = "insert into banzu (BANZU_NAME,FUZEREN,BANZUCHENGYUAN) VALUES(?,?,?)";

      //获得事务状态描述

      TransactionStatusstatus = transactionManager.getTransaction(def);

      try{

         if(banzu!=null)

         {

           

            this.jdbcTemplate.update(sql,new Object[]{banzu.getBanZu(),banzu.getFuZeRen(),banzu.getChengYuan()});

            //该处插入有错误会报异常的

           jdbcTemplate.update("insetinto banzu (BANZU_NAME,FUZEREN,BANZUCHENGYUAN) VALUES(?,?,?)", newObject[]{"222","333","444"});

         }

      }catch(DataAccessExceptione){

         transactionManager.rollback(status);

         throwe;

      }

//这里只有不报SQL异常下面的commit才会提交执行的sql语句到库中

   transactionManager.commit(status);

   }

……

}

这里使用了DataSourceTransactionManager对象,他实现了platformTransactionManager,继承自AbstractPlatformTransactionManager,是针对于特定数据源的事务操作管理类。其中方法:

doBegin(…)

doResume(…)

doSuspend(…)

doCommit(…)

doRollback(…)

等操作方法,而且其中还定义了相应的内部静态类:DataSourceTransactionObject对象可以实例化事务对象

private staticclassDataSourceTransactionObject extends JdbcTransactionObjectSupport {

      private boolean newConnectionHolder;

      private boolean mustRestoreAutoCommit;

      public voidsetConnectionHolder(ConnectionHolder connectionHolder, booleannewConnectionHolder){

         super.setConnectionHolder(connectionHolder);

         this.newConnectionHolder= newConnectionHolder;

      }

      public boolean isNewConnectionHolder(){

         return this.newConnectionHolder;

      }

   public voidsetMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {

         this.mustRestoreAutoCommit= mustRestoreAutoCommit;

      }

      public booleanisMustRestoreAutoCommit() {

         return this.mustRestoreAutoCommit;

      }

      public void setRollbackOnly() {

         getConnectionHolder().setRollbackOnly();

      }

      public boolean isRollbackOnly() {

         returngetConnectionHolder().isRollbackOnly();

      }

}

#DataSourceTransactionManager调用的getTransaction()、rollback()、commit()等都来自于AbstractPlatformTransactionManager类中的实现。

 

#AbstractTransactionDefinition实现了TransactionDefinition接口,主要设置相关事务的ACID属性,传输性、隔离性、只读、超时限制,具体的可以参考spring的事务1.

 

此外另一个实现式的编程式事务管理的方法是使用了TransactionTemplate,它简化了编程式事务的分工和异常的处理。其核心的方法是execute,实现了TransactionCallback接口,支持可编程的事务方式。

 

其构造方法中有一个需要platformTransactionManager参数的

Public TransactionTemplate(PlatformTransactionManagertransctionManager){

   This.transactionManager= transactionManager;

}

然后讲下该方法,也是TransactionTemplate的核心方法。

   public <T> Texecute(TransactionCallback<T> action) throwsTransactionException {

/*实现CallbackPreferringPlatformTransactionManager接口的可以返回一个transactioncallback的应用,transactioncallback则是对于transaction操作的一个接口。*/

      if (this.transactionManagerinstanceofCallbackPreferringPlatformTransactionManager) {

         return((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this,action);

      }

      else {

//通过transactionDefinition获得一个事务,并返回其状态信息

         TransactionStatusstatus= this.transactionManager.getTransaction(this);

         Tresult;

         try {

//事务中处理操作,返回结果

            result = action.doInTransaction(status);

         }

         catch (RuntimeException ex) {

            //出现sql异常,回滚

            rollbackOnException(status, ex);

            throw ex;

         }

         catch (Error err) {

            //编程式事务异常抛出error回滚 threw error ->rollback

            rollbackOnException(status, err);

            throw err;

         }

         catch (Exception ex) {

            // Transactional code threw unexpected exception ->rollback

            rollbackOnException(status, ex);

            throw newUndeclaredThrowableException(ex, "TransactionCallback threw undeclaredchecked exception");

         }

//不抛出异常的话,将执行的sql内容提交到数据库

         this.transactionManager.commit(status);

         return result;

      }

   }

因此可以看到使用TransactionTemplate时,需要借助一个transactionManager,然后执行execute方法,可以直接使用匿名内部类:

transactionManager.execute(newTransacitonCallback(){

      publicObject doInTransaction(TransactionStatus status){

         return jdbcTemplate.update(“….”);

}

});

如果发生了异常,则会rollback,否则提交事务。如果没有返回值的话也可以使用TransactionCallbackWithoutResult.

 

public voidsetDataSource(DataSource dataSource){

      this.jdbcTemplate = new JdbcTemplate(dataSource);

      transactionManager= newDataSourceTransactionManager(dataSource);

      //建立事务定义,明确传输行为为:支持当前事务,如果当前没有则新建

      //def = new DefaultTransactionDefinition();

      //def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

      //使用transactionTemplate

      this.transactionTemplate= newTransactionTemplate(transactionManager);

   }

//在匿名内部类中使用的外部变量,需要声明成final类型,保持一致。

   @Override

   public void saveBanzu(final Banzu banzu) {

      // TODO Auto-generated method stub

      final String sql = "insert into banzu(BANZU_NAME,FUZEREN,BANZUCHENGYUAN) VALUES (?,?,?)";

      transactionTemplate.execute(newTransactionCallback<Object>(){

            public ObjectdoInTransaction(TransactionStatus status){

                jdbcTemplate.update(sql, new Object[]{banzu.getBanZu(),banzu.getFuZeRen(),banzu.getChengYuan()});

                return null;

            }

      });

 

   }

使用TransactionTemplate时则是使用其内部的事务处理,只要调用其execute方法,实现TransactionCallback匿名内部类即可。


对于TransactionTemplate的另一个方法

#rollbackOnException()

private voidrollbackOnException(TransactionStatus status, Throwable ex)throwsTransactionException {

      logger.debug("Initiating transaction rollback on applicationexception", ex);

      try {

         this.transactionManager.rollback(status);

      }

…可以看到它是private私有的,也就是在其内部调用。也就是在execute方法内部如果出现了异常会调用它。

下面是相应的这部分的类结构关系:


关于声明式事务管理下次继续。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值