很早就注意到了微软的MTS COM+,但是却很少使用,主要原因是因为它的第一次执行太慢,耗费的资源比较多。在服务器配置比较乐观的项目里,比如某移动公司和某知名跨国日化生产商的系统里,恰当地使用COM+反而使得整体负载和程序的框架变得很清晰。

    在castle中集成了NHibernateIntegration对NHibernate进行了集成,对Session和Transaction进行了很好的封装。但是在对发布的beta版进行了最基本的测试后,我发现这个开源的东西还比较简陋。于是通过SVN获取了最新的开发版本,发现已经完全重写了。所以我就一个经典的转账来看看他们各有怎样的表现.


测试场景:
  我们假设一个娱乐中心要通过银行把钱转给在本中心娱乐的那些玩家中的获奖者,娱乐中心的账号设在bank1;而获奖者的账号都在bank2.  以下是转账的规则:

1) 娱乐中心没有钱肯定不能转帐;
2) 一次转账额不能超过5000;
3) 银行账号不能有重复;

    在很多的经典例子中,都太简单,这里我们模拟在每次都转到新开账号上,如果对第二次转帐到同一玩家,您讲看到一个异常。我们看看这两个容器是否能经受考验!

以下就是针对COM+ 的程序片断:

实践篇(3)--关于事务处理的一点细节using System;
实践篇(3)--关于事务处理的一点细节
using System.Data;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using System.Reflection;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using System.EnterpriseServices;
实践篇(3)--关于事务处理的一点细节
using System.Runtime.InteropServices;
实践篇(3)--关于事务处理的一点细节
using Dao;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节[assembly: ApplicationName(
"COM+ demo")]
实践篇(3)--关于事务处理的一点细节[assembly: ApplicationActivation(ActivationOption.Library)]
实践篇(3)--关于事务处理的一点细节
}


在MTS里运行COM+,您的相关组件必须使用强名称,请注意要把
[assembly: AssemblyVersion("1.0.0.0")] 明确设定,否则每次运行在组件管理其中都会产生新的版本。

我们再看看NHibernateIntegration的表现如何:

实践篇(3)--关于事务处理的一点细节using System;
实践篇(3)--关于事务处理的一点细节
using System.Collections;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using Demo.Entities;
实践篇(3)--关于事务处理的一点细节
using Castle.Services.Transaction;
实践篇(3)--关于事务处理的一点细节
using Castle.Facilities.NHibernateIntegration;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using NHibernate;
实践篇(3)--关于事务处理的一点细节
using NHibernate.Expression;
实践篇(3)--关于事务处理的一点细节

而上层的服务代码如下:
实践篇(3)--关于事务处理的一点细节using System;
实践篇(3)--关于事务处理的一点细节
using System.Collections;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using Demo.Entities;
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节
using NHibernate;
实践篇(3)--关于事务处理的一点细节
using Castle.MicroKernel;
实践篇(3)--关于事务处理的一点细节
using Castle.Services.Transaction;
实践篇(3)--关于事务处理的一点细节
}
castle配置文件如下:

实践篇(3)--关于事务处理的一点细节<?xml version="1.0" encoding="utf-8" ?>
实践篇(3)--关于事务处理的一点细节
<configuration>
实践篇(3)--关于事务处理的一点细节    
<facilities>
实践篇(3)--关于事务处理的一点细节        
<facility id="nhibernate">
实践篇(3)--关于事务处理的一点细节            
<!-- 数据库一 -->
实践篇(3)--关于事务处理的一点细节            
<factory id="demo1">
实践篇(3)--关于事务处理的一点细节                
<settings>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.connection_string">Server=localhost;Database=demo1;Uid=sa;Pwd=</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</item>
实践篇(3)--关于事务处理的一点细节                
</settings>
实践篇(3)--关于事务处理的一点细节                
<resources>
实践篇(3)--关于事务处理的一点细节                    
<resource  name="./Account.hbm.xml" />
实践篇(3)--关于事务处理的一点细节                
</resources>
实践篇(3)--关于事务处理的一点细节            
</factory>
实践篇(3)--关于事务处理的一点细节            
<!-- 数据库二 -->
实践篇(3)--关于事务处理的一点细节            
<factory id="demo2" alias="db2">
实践篇(3)--关于事务处理的一点细节                
<settings>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.connection.connection_string">Server=localhost;Database=demo2;Uid=sa;Pwd=</item>
实践篇(3)--关于事务处理的一点细节                    
<item key="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</item>
实践篇(3)--关于事务处理的一点细节                
</settings>
实践篇(3)--关于事务处理的一点细节                
<resources>
实践篇(3)--关于事务处理的一点细节                   
<resource  name="./Account.hbm.xml" />
实践篇(3)--关于事务处理的一点细节                
</resources>
实践篇(3)--关于事务处理的一点细节            
</factory>
实践篇(3)--关于事务处理的一点细节        
</facility>
实践篇(3)--关于事务处理的一点细节        
实践篇(3)--关于事务处理的一点细节    
</facilities>
实践篇(3)--关于事务处理的一点细节
实践篇(3)--关于事务处理的一点细节    
<components>    
实践篇(3)--关于事务处理的一点细节        
实践篇(3)--关于事务处理的一点细节         
<component id="bank2" >
实践篇(3)--关于事务处理的一点细节          
<parameters>
实践篇(3)--关于事务处理的一点细节                
<DbTag>db2</DbTag>
实践篇(3)--关于事务处理的一点细节            
</parameters>
实践篇(3)--关于事务处理的一点细节         
</component>
实践篇(3)--关于事务处理的一点细节       
</components>
实践篇(3)--关于事务处理的一点细节
</configuration>
实践篇(3)--关于事务处理的一点细节


通过改造NHibernateIntegration,我们可以在输出窗口看到执行过程:
1) 启动Transfer事务;
2) 启动Withdraw事务;
3) 完成Withdraw处理;
4) 启动CrateNewAccount处理;
5) 完成CrateNewAccount处理;
6) 对bank1和bank2进行数据库事务提交;
7) 完成Transfer事务;

结论:
首次执行COM+明显慢一些;
COM+的逻辑没有发生混乱;而NHibernateIntegration在没有及时进行缓存刷新时发生了严重的逻辑错误并且不能回滚。


另外我在一些有递归的情况下进行测试发现:使用延迟加载会出现session closed 或者访问空值得异常情况。
让我们期待NHibernateIntegration的完善吧......

alex

 



 

相关文章: