新事务之一: dotNET和COM+中的事务
小气的神
2002-4-16
Article Type: In-Depth
难度等级:6/9
版本:2.32
COM+早于dotNET出现,并且在这几年成为我们在Windows平台下进行分布式和企业级开发的一个解决方案和操作平台,它预置了一些面向企业级应用的通用和底层设施,特别是多层应用模型的中间层的基础设施模块,借助它可以使得开发人员有更多的精力放在应用的业务逻辑本身,有趣的是有时它并不真的让我们满意,值得一提的是从它的父辈开始,都一直是操作系统的一部分。dotNET则是Microsoft最近发表的下一代的一个面向Web的开发平台,比起它所有的前任都显得野心勃勃和气势庞大,所以说足够疯狂和让人振奋。对于dotNET来说COM+是一个成熟而意义重大的历史伙伴,而对于COM+来说dotNET是一个新鲜而略带侵略性的新贵朋友,无论两者如何,对于相对局外的开发人员来说,如何和它们相处和交互将成为一个不小的瓶颈,有些糟糕的是dotNET和COM+在我们之外,而且在不断发展和变化。所以一定有一些有趣的事情,而我们把范围缩小,聚焦在我们开发过程中可能密切相关的事务编程上,可以说,变化带来了许多新的变化而且也带来了许多开发人员的新的思考,在后面的文章中你们会陆续看到他们的思考给我带来的启发和益处,那么希望同样也能给更多的人带来启发和思考。
消除一些模糊的概念
一段时间以来我们对dotNET、CLR、COM、COM+存在一些模糊不清的概念,dotNET是Microsoft定义的下一代的开发平台。CLR(Common Language Runtime)是dotNET的核心和心脏,也是Microsoft对ECMA规范的一个Windows平台的实现。COM(Component Object Model)是一个组件对象模型,提供了组件之间交互和作用的基本机制和原则,它是一项组件开发技术和编程模型。COM+是一个组件运行环境,是提供了一系列有关分布式系统功能的Services集合的组件运行环境和工具包。CLR替代了COM,但是无法也没有替代COM+,COM+现在叫.NET Enterprise Services,当然如果不带.NET的前缀,Enterprise Services最能体现COM+的作用和定义。CLR离应用层近一些,而COM+离操作系统更近一些,对于最近的Windows.NET的操作系统对COM+进行的一系列增强:Application Partitioning、Application Pooling and Recycling、Resource Manager、Configurable Transaction Isolation Level、Web Services等等(详见Juval Lowy的文章)来说,有些低级的程序API,CLR还根本无法有相应的功能提供,还需要wrapping 这些新的COM+ APIs。当然不能肯定未来的未来,这些COM+的API是用C#或其它的CLR-managed API直接实现。目前可以说,如果以前你用COM技术在COM+环境下工作的很好(或者很痛苦),那么现在用CLR在COM+下工作起来一样也很好,并且要方便,快捷;dotNET使得开发人员使用COM+更加方便和有效率,这就如同许多年以前从字符键盘界面(COM)引入图形鼠标界面(dotNET)是对计算机的使用(COM+)的一场革命一样。
dotNET中使用COM+的事务服务
dotNET环境下使用COM+以及事务服务要经过下面一些步骤:
1. 实现一个COM+的Configured类
我们只用从System.EnterpriseServices.ServicedComponent继承一个自己的类,然后提供一个缺省的构造函数
2. 声明分布式事务
只用这类名前面加事务属性即可比如:[Transaction(TransactionOption.Required) ]
3. 提交事务
IObjectControl::SetComplete或是直接使用自动完成属性 [AutoComplete()]
4. 其它的IObjectConstruct、IObjectControl、Pooling、JustInTimeActivation
A) IObjectConstruct :类名前加[ConstructionEnabled(Default="Connection String")]属性,然后覆盖方法 public override void Construct(string constructString){}
B) Pooling:类名前加属性[ ObjectPooling(true, 3,30) ],然后覆盖CanBePooled方法,public override bool CanBePooled() { return true; }
C) JustInTimeActivation :加属性[ JustInTimeActivation(true) ]
5. 编译和分发
a) 组件注册
[assembly: ApplicationName("MydotNetCOMApp")]
[assembly: ApplicationActivation(ActivationOption.Library)]
b) 组件强名
[assembly: AssemblyKeyFile("keyfile.snk")]
这一步如果先产生sn.exe 产生.snk文件然后在VS.NET IDE中打开AssemblyInfo.cs,加入上面的一行似乎更方便这样就不用手工的csc编译了,VS.NET可以编译强名的Assembly。尝试使用AssemblyInfo.cs会更规范和统一。
c) 编译组件
sn -k keyfile.snk
csc /out: dbClass.dll /t:library /r:System.EnterpriseServices.dll dbClass.cs
d) 发布登记
Regsvcs dbClass.dll (Regsvcs自动调用regasm.exe和tlbexp.exe)
一个大致的文件可能向下面这样,先原谅我展示了太多的属性:)
using System; using System.EnterpriseServices; // Namespace necessary for creating COM+ application using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices;
[assembly: ApplicationName("COMPlusSamplesLib")] [assembly: ApplicationActivation(ActivationOption.Library)]
//[assembly: AssemblyKeyFile("..//..//keyfile.snk")]
namespace dotCNetwork.dbClass { /// <summary> /// Summary description for Class1. /// </summary> [ConstructionEnabled(Default="server=localhost;uid=sa;pwd=;initial catalog=pubs")] //[ EventTrackingEnabled ] [ObjectPooling(MinPoolSize=2,MaxPoolSize=50)] [ Transaction(TransactionOption.Required) ] [ Synchronization(SynchronizationOption.Required) ] [ JustInTimeActivation(true) ] [Guid("569A14C1-5DAD-4c8f-BB48-89DDD89FAD7A")] public class Author : ServicedComponent { private const string CONNSTRING="server=localhost;uid=sa;pwd=;initial catalog=pub";
private string ConnString ;
public Author() { // // TODO: Add constructor logic here // }
//JIT/Pooling protected override void Activate() {} // JIT/Pooling protected override void Deactivate() {}
//JIT/Pooling protected override bool CanBePooled() { return true ; }
//Construct String protected override void Construct( string s ) { if( s.Length== 0 || s == null) { ConnString = CONNSTRING; } ConnString = s ; }
//my Function public bool alive() { try { // Commit the transaction ContextUtil.SetComplete(); return true ; } catch(Exception e) { ContextUtil.SetAbort(); return false ; } }
[AutoComplete] public string GetConnectionStr() { return ConnString; }
} }
|
关于如何生成一个dotNET的组件并且注册到COM+环境中以及客户端如何调用的具体步骤和实例我就跳过了,请参照Microsoft的标准规范和建议。
(未完)
特别:
本文CSDN署名首发,转载或改编请注明作者和出处。如果有问题,请发电子邮件给new2001@msn.com
以上文字和图片涉及其他人的隐私和个人权利,所有文字和图片只用于内部交流,不作任何新闻发表和商业用途。