今天看了由Juval Lowy作的一篇技术白皮书《Introduce System Transaction》,大概对.Net 2.0中对Transaction的创新有了个大概的了解。在看这篇文档时我想起Rod Johnson的那本《Expert One-on-One J2EE Development without EJB 》,其作者在书中陈述EJB中Transaction的诟病时引用了对.Net Framework 1.x 中的Enterprise Service中对事务的声明型支持,而在他对Spring的介绍中,我觉得他是借鉴了这样的思想的,通篇作者多次提到.Net Framework中的一些设计模式和特性,想来语言抽象到现在这个地步,对于企业应用开发,不论Java还是.Net 都会有更多互相借鉴的特性和框架。扯远了,这里说起这件事也是对那本书的回忆,虽然我没有从事Java开发,那本书让我学到的东西还是很多的,Rod Johnson是Spring的创始人之一。模式和框架都是搞企业应用开发的人追求的,是软件开发的形而上的玩艺。
现在对事务的编程方式大概分两种:显式地事务管理模式(explicit transaction management programming model) 和 声明型事务模式(declarative programming model)
正如我从那本书中关于声明型事务的理解,声明型的事务支持大抵需要一个封闭环境(Context)或容器支持,就是说你在这个环境下时,只需要声明一下你要用事务了,在整个声明的周期或范围里,你对支持事务的资源的操作都是在事务管理中的。这个在.net 1.x时,System.EnterpriseService有很好的支持:
using System.EnterpriseServices;
[Transaction]
public class MyComponent : ServicedComponent
{
[AutoComplete] // 让Context自动完成事务:没有错误则执行(Commit),有错误则放弃(Abort)
public void MyMethod()
{
/* 与 其他ServicedComponent 或 事务资源管理者 操作*/
}
}
这里有个概念叫事务资源管理者(Transaction Resource Manager),我的理解是诸如SQL Server,Oracle,DB2等数据库(资源)必须提供事务管理的支持,否则何谈对资源进行事务(如果一个资源(Resource)本身没有事务支持,就要客户端自己想法子来支持事务,比如对每个操作都要有个逆向操作;同时还要想法子支持隔离机制)。
声明型所依赖的环境就就是和这些资源管理者打交道的,所以声明型依赖的环境(Context)就起到了这个事务管理者的角色,离开了这个环境(Context)管理事务就要开发者自己显式地管理事务,.Net 中是这样显式地进行事务操作的,
IDBConnection conn = new SqlConnection();
conn.Open();
IDBTransaction trans = conn.BeginTransaction();
Try
{
/* 做些与事务相关的操作 */
trans.Commit();
}
catch(Exception ex)
{
trans.Rollback();
throw ex;
}
finally
{
conn.Close();
}
这样比较烦,得自己负责事务的打开和回滚,用起来不方便,所以这是声明型事务编程模式受欢迎和重视的原因所在,而在.net 1.x中要使用声明型事务得去用System.EnterpriseService,除非自己去搞一套来支持声明型事务编程。
要想用声明型事务编程,正如上面说的得要一个环境(Context)来支持,.Net Framework2.0 就给我们创新了一个“环境”来封装事务管理,从而支持声明型事务编程,这个“环境”就是 TransactionScope.
关于那个TransactionScope到底是何方神圣,且听下回分解。