从源码理解spring事务(1)

         在介绍spring事务之前,首先弄清楚什么是事务。事务是访问数据库中各种数据项的一个程序执行单元,他满足ACID的特性,事务是恢复和并发控制的基本单位。那么什么又是spring事务?spring事务能够做哪些事?使用spring事务的好处是什么?

         众所周知,Spring是一块主板和粘合剂,spring中也定义了一个整体的,与spring其他组件无缝衔接的事务基础,具体来说,PlatformTransactionManager就是一个能够适用各种事务和数据源的接口,接口定义如下。通过这个接口,spring不仅能够操作JDBC的事务,同时也能够操作诸如hibernate,JTA等事务类型。带来的好处是显而易见的,首先是统一的实现,无缝的衔接,真正的高内聚低耦合的设计;其次,简化了丑陋的try-catch-finally的普通事务写法,通过这部分的封装,降低了编码的难度;再次,通过声明式事务编程,实现了可配置的事务管理。

public interface PlatformTransactionManager {
	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
}

         从UML图可以看出,跟PlatformTransactionManager相关的核心接口有TransactionStatus以及TransactionDefinition(可以看到spring把面向接口编程贯彻得非常好)


         在开始之前,我们首先来回顾一下不使用任何框架时我们是如何去操纵JDBC并且完成事务过程的。可以看到,在代码段transaction1中,我们首先要把自动提交设置为false,然后在try块中做我们带事务的的业务逻辑,在catch块中回滚,并且在finally块中释放资源。

public void transaction1() throws Exception {
		Connection conn = MysqlDatasource.getConnection();
		conn.setAutoCommit(false);
		try {
			// doSomeThing();
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
		} finally {
			try{
				conn.close();
			}catch(Exception e){
				//error process
			}
		}
	}

           我们来看一个重要的问题,要想在spring中控制其他事务源的事务,他需要做什么,见下面代码段transaction2。如前面提到的,spring提供了PlatformTransactionManager来抽象具体事务策略,从而通过抽象的transactionManager来代理具体的事务控制,transaction2其实非常类似transaction1,不同的是,它被抽象了,这个transactionManager可以代理transaction1中的Connection。从这里我们可以很好的学习到spring是如何去充当一个总理或者一块主板功能的,奥秘就是一个高级的抽象。由于PlatformTransactionManager是一个接口,可以想象,凡是遵循该接口定义的事务实现策略都可以被粘合到spring中,所以你可以看到JtaTransactionManager,DataSourceTransactionManager, JdoTransactionManager, HibernateTransactionManager等都是spring中能够支持的事务策略类。

public void transaction2() throws Exception {
		TransactionDefinition def = new DefaultTransactionDefinition();
		TransactionStatus status = transactionManager.getTransaction(def);
		try {
			// doSomeThing();
			transactionManager.commit(status);
		} catch (Exception e) {
			transactionManager.rollback(status);
		}
		// return result object
	}

           上面这段程序或许你并不觉得烦琐,但是要知道,在一个企业级系统中,可能有成千上万个这样有待事务控制的方法,将上面这段程序重复1000次?我想我们都会汗颜。

           我们来看看spring是如何简化我们的工作。Spring事务的初衷就是砍掉这部分多余的代码,在这个例子中,除了doSomeThingA(),doSomeThingB()这两段业务逻辑代码,其余都是多余的。为了达到这个目的,编程式事务的帮助类TransactionTemplate采用了回调去执行业务逻辑,关键代码如下。可以看出,我们只需要把真正需要做事务的业务逻辑包装在doInTransaction中就行了。

public void myBusiness(){
		transactionTemplate.execute( new TransactionCallback<Object>(){
	        public Object doInTransaction(TransactionStatus ts){ //do sth
	        	return "";
	        }
	    });
	}

            而这个回调的业务逻辑事实上正是被包在了类似transaction2的程序中,见如下spring源码之TransactionTemplate,事实上,回调是spring中大量使用的技巧(据说win32编程没其他更多技巧,唯回调而已),使用了TransactionTemplate的代码更加简洁,bug更少,可维护性更好,而且可以使用platformTransactionManager的模拟对象测试而无需JTA环境,因此更易于测试。

public <T> T execute(TransactionCallback<T> action) throws TransactionException {
		if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
			return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
		}
		else {
			TransactionStatus status = this.transactionManager.getTransaction(this);
			T result;
			try {
				result = action.doInTransaction(status);
			}
			catch (RuntimeException ex) {
				// Transactional code threw application exception -> rollback
				rollbackOnException(status, ex);
				throw ex;
			}
			catch (Error err) {
				// Transactional code threw error -> rollback
				rollbackOnException(status, err);
				throw err;
			}
			catch (Exception ex) {
				// Transactional code threw unexpected exception -> rollback
				rollbackOnException(status, ex);
				throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
			}
			this.transactionManager.commit(status);
			return result;
		}
	}

            很快就会有人提出问题了,回调是一种简化代码比较好的方式,但是调用回调的匿名方法并不够优雅,看起来声明式事务管理是更优雅的方式,因为我们终于可以不用在代码段看见事务相关的代码了,我们彻底解放了。

            待续……


参考文档:

事务定义http://baike.baidu.com/view/121511.htm

Spring事务原理 http://www.blogjava.net/dragonofson/articles/54690.html

Spring开发之事务管理http://tech.ccidnet.com/art/3539/20060323/487865_1.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值