** 新事务之一: ** ** 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
{
///
1<summary>
2
3/// Summary description for Class1.
4
5/// </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 署名首发,转载或改编请注明作者和出处。如果有问题,请发电子邮件给 [email protected]
以上文字和图片涉及其他人的隐私和个人权利,所有文字和图片只用于内部交流,不作任何新闻发表和商业用途。