是否可以在.Net应用程序和COM +对象之间共享事务?
我前段时间做了一些测试,但从未想出如何进行这项工作。
这些成分:
- COM +事务对象(在VB6中开发)
- IIS中的.Net Web应用程序(带有事务处理)...调用COM +组件会更新SQL数据库中的一行
测试:
运行.Net应用程序并强制执行异常。
结果:
从.Net应用程序进行的更新将回滚。
COM +对象所做的更新不会回滚。
如果我从旧的ASP页面调用COM +对象,则回滚有效。
我知道有些人可能会在想"什么?!COM +和.Net我们一定不在头脑中!",但是这个世界上有些地方仍然有很多COM +组件。我只是好奇是否有人遇到过这个问题,以及我们是否想出了如何使它起作用的方法。
解决方案
回答
我们如何实施呢?如果我们使用EnterpriseServices来管理.NET事务,则这两个事务都应回滚,因为我们对两个事务都使用相同的上下文。
回答
因为VB和.NET将使用不同的SQL连接(并且无法使ADO和ADO.NET共享相同的连接),所以唯一的可能性就是征募DTC(分布式事务处理协调器)。 DTC将协调两个独立的事务,以便它们一起提交或者回滚。
通过.NET,EnterpriseServices管理COM +功能,例如DTC。在.NET 2.0及更高版本中,可以使用System.Transactions命名空间,这会使事情变得更好。我认为这样的事情应该起作用(未经测试的代码):
void SomeMethod() { EnterpriseServicesInteropOption e = EnterpriseServicesInteropOption.Full; using (TransactionScope s = new TransactionScope(e)) { MyComPlusClass o = new MyComPlusClass(); o.SomeTransactionalMethod(); } }
我对此还不太熟悉,无法在此时给我们更多建议。
在COM +端,需要将对象配置为使用(很可能是"要求")分布式事务。我们可以通过COM +资源管理器执行此操作,方法是转到对象的"属性",选择"事务"选项卡,然后单击"必需"。我不记得我们是否也可以通过代码来完成此操作。 VB6是在COM +发布之前创建的,因此它不完全支持COM +所做的一切(它的事务支持是给COM +的前身MS Transaction Server的)。
如果一切正常,则COM +对象应加入.NET代码创建的现有上下文中。
我们可以使用"组件服务"中的"分布式事务处理协调器\事务列表"节点来检查并查看在调用过程中正在创建的分布式事务。
请注意,在提交事务之前,我们无法看到来自.NET端的数据查询所反映的COM +组件的更改!实际上,可能会陷入僵局!请记住,DTC将确保两个事务配对,但是它们仍然是独立的数据库事务。