新事务之一: dotNET和COM+中的事务(1)

** 新事务之一: ** ** 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]

以上文字和图片涉及其他人的隐私和个人权利,所有文字和图片只用于内部交流,不作任何新闻发表和商业用途。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus