English 中文(简体)
避免在 System.Transactions 中出现交易升级的策略
原标题:
  • 时间:2008-12-27 17:43:49
  •  标签:

因此,根据我的上一个问题的回答,如果在一个事务中打开多个连接,即使这些连接全部使用相同的连接字符串,事务也会从LTM升级到DTC。

那么,我的下一个问题是,有什么策略可以避免这种“特性”?我觉得,基于资源使用情况,我想要确保长期记忆(LTM)尽可能地被使用。在正确的面向对象业务逻辑层中,我所能想到的唯一方法是,在数据访问层创建一个请求级别的静态连接对象,并在调用之间共享,直到请求完成(暗含的知识是业务对象实体是离散的,不知道它们将被调用的顺序,另外一个事实是不能将连接对象推到业务对象层,因为那将是数据存储实现细节渗透到另一层)。

还有其他人有没有任何想法,不会完全破坏n层系统的层次封装?

问题回答

我使用了TransactionHelper类来更新所有命令中的TableAdapter,以便用启动事务的TableAdapter 中的连接和事务替换。您可以在Scott Lanford的博客CodeExperiment上找到一些代码,可以根据需要进行调整。Ryan Whitaker也有类似的方法。

请注意,由于我现在已经开始使用LINQToSQL,我不再遇到这个问题。您可能希望考虑使用LINQToSQL或nHibernate作为替代方案。无论哪种方案都会有很好的本地事务支持。

我建议编写一个包装类来管理连接、事务、命令对象,就是整个 DB 事物。这有点像一个非常轻量级的 nHibernate。这个类将提供 executeStatement(...)、executeQuery(...)、addParameter(...)、startTransaction(...) 等方法。

当启动一个事务时,你可以提供一个(如果需要唯一的)标识符,以便将所有关于同一事务的后续请求绑定在一起。这个包装类会保存一个静态映射,表明正在运行哪个连接的哪个事务,并根据需要自动使用正确的连接或创建一个新的连接。

你会从这个方法中获得一些额外的功能,因为你已经集中了你所有的持久化内容:

  • easily log all statements for debugging, performance testing
  • automatic retry logic on locking/network problems
  • simpler switch of DB provider
  • basically some of the things you get with persistence frameworks like nHibernate, but more lightweight and not so sophisticated

我必须问一下,试图如此努力避免DTC的原因是什么?在这个或上一个答案中都没有提到为什么,这似乎表明您可能正在遭受过早优化综合症。

正如卡斯帕所说,避免 DTC 可能还为时过早,尽管它是一个重要的问题。你可以使用静态工厂来实现你的连接,以便简单地返回新的对象,然后如果你确定你有一个问题,你可以实现一个机制,可以将事务存储在一个 TLS (或 httpcontext,如果你在 ASP 中) 中。而不需要改变任何代码。

这个问题实际上已经被问过并且回答了,但当我找到时我将更新此问题。





相关问题
热门标签