【问题标题】:Strategies to Avoid Transaction Escalation in System.TransactionsSystem.Transactions 中避免事务升级的策略
【发布时间】:2008-12-27 17:43:49
【问题描述】:

因此,根据对my previous question 的回答,如果在事务期间打开了多个连接,即使这些连接都具有相同的连接字符串,事务 确实 也会从 LTM 提升到 DTC .

那么,我的下一个问题是,可以采用什么策略来避免这种“功能”?在我看来,根据资源使用情况,我想确保尽可能多地使用 LTM。在正确面向对象的业务逻辑层中,我能想到的唯一方法是在数据访问层创建一个请求级静态连接对象,并在调用之间共享该对象,直到请求完成(这里的隐含知识是业务对象实体是谨慎的并且不知道它们会被调用的顺序,另外一个事实是人们不希望将连接对象冒泡到业务对象层,因为那将是数据存储实现细节渗入另一层)。

还有其他人有什么想法不会完全破坏 n 层系统的层封装吗?

【问题讨论】:

  • 这是一个很好的问题,我也在寻找答案。所有的答案在简单的例子中总是不足的,但从不考虑封装。
  • 顺便说一句,由于问题已过时,您如何解决?我正在考虑使用“环境”连接并在内部进行一些事务计数。这很糟糕,我知道。

标签: architecture ado.net transactions n-tier-architecture system.transactions


【解决方案1】:

我使用的是 TransactionHelper 类更新 TableAdapter 中的所有命令,以将连接和事务替换为启动事务的 TableAdapter 中的那些。您可以在 Scott Lanford 的博客 CodeExperiment 上找到 some code that does this,您可以根据需要进行调整。 Ryan Whitaker 有一个similar approach

请注意,自从我开始使用 LINQToSQL 后,我不再遇到此问题。您可能需要考虑使用 LINQToSQL 或 nHibernate 作为替代解决方案。两者都可以很好地支持本地事务。

【讨论】:

  • 我不使用 TableAdapter,我使用 SqlDataAdapter,它接受一个命令对象,并且完全支持开发人员设置命令对象(以及连接对象)。然而,这并没有解决离散对象调用 DAL 的问题,需要相同的 con。
  • 我也在避免 LINQ to SQL 像瘟疫一样。有很多事情我不喜欢它,但我不喜欢它。
【解决方案2】:

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

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

您将从这种方法中获得一些额外的功能,因为您将集中所有持久性内容:

  • 轻松记录所有语句以进行调试、性能测试
  • 锁定/网络问题的自动重试逻辑
  • 更简单的 DB 提供者切换
  • 基本上是您使用 nHibernate 等持久性框架获得的一些东西,但更轻量级且不那么复杂

【讨论】:

    【解决方案3】:

    我不得不问,为什么要如此努力地避免 DTC?在这个或上一个答案中没有提到为什么,它看起来好像你可能患有过早的优化综合症。

    【讨论】:

    • 避免 DTC 只是一个好习惯。当您知道您的事务将被升级并且它们不必如此时,这并不是一个过早的优化。 DTC 比轻量级事务协调器慢WAY,因此应该避免。
    • DTC 并不总是有效。我浪费了一个下午调试一个带有神秘错误配置 DTC 的服务器,结果发现许多人的服务器带有 DTC 服务,这些服务器不知何故失控、被禁用,并且不愿意协调事务。
    • @Robert C. Barth:为了避免 DTC 而避免 DTC 不是好的或推荐的做法,它完全取决于情境。你的陈述是笼统的,并没有提供太多的理由。至于知道您的事务何时将被升级,那不是 TransactionScope 的错,那是编码器的错,应该围绕它进行编码,因为他们知道它的行为。此外,仅仅因为某些东西较慢,并不意味着应该避免它。 DTC 提供了其他方式无法获得的优势。
    • 我不是为了避免它而试图避免它......我是在避免它,因为事务发生在单个数据库服务器中并且不需要 DTC。您对知道交易何时会被提升以及我应该围绕它进行编码的评论正是我要问的......我如何围绕它进行编码?这就是问题的重点。 DTC的特性在单服务器MS SQL Server后端上下文中是没用的,也就是本题的上下文。
    【解决方案4】:

    正如 casper 所说,避免 DTC 可能为时过早,尽管它很重要。您可以使用静态工厂实现您的连接,以便简单地返回新对象,然后如果您确定您有问题,您可以实现一种机制,可以将事务存储在 TLS(或 httpcontext,如果您在 ASP 中)中。并且不必更改任何代码。

    这个问题实际上已经被问到并得到了回答,但是当我找到它时我会更新它。

    【讨论】:

    • 我在发帖前进行了搜索,但我找不到一个稍微相似的问题。也许通过搜索 Skillz 需要更新。 ;-)
    • 使用 Google 搜索添加 site:stackoverflow.com 以限制到此站点。 SO 的搜索能力低于标准
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2011-08-14
    • 2011-05-08
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多