跨应用程序域的事务管理






3.89/5 (4投票s)
本文详细介绍了跨应用程序域事务管理的最佳实践。
引言
一段时间前,我们正在开发一个应用程序,其中涉及多个级别的事务。
有时我们只需要更新一个数据库,有时需要从单个应用程序域更新多个数据库,还有一些场景是我们正在更新跨应用程序域的多个数据库,这些数据库通过 WCF 服务公开。
正如你所见,随着参与方数量的增加以及参与的应用程序域数量的增加,这些事务管理问题会变得更加复杂。
在本文中,我们将介绍事务,MSDTC 如何帮助我们,如何在 SQL Server、.NET 和 WCF 中处理它们。这将为关于如何在异构环境中管理事务的文章打下基础。
有很多关于一些基础知识的优秀文章,因此在给出简要概述后,我会指向更好、更详细的文章。此外,本文的受众是架构师和设计师。我假设我们大多数人已经了解这些概念,只有少数人可能需要快速回顾一下。
本文面向应用程序架构师和设计师,涉及逻辑设计问题,因此不包含任何代码。
什么是事务
事务是一组具有以下属性的操作:原子性、一致性、隔离性和持久性(ACID)。
这意味着对于数据库或数据存储,要么所有数据库都已更新,要么没有数据库被更新。
MSDN 上的这篇文章提供了关于此主题的大量详细信息。
什么是 MSDTC
MSDTC 代表 Microsoft 分布式事务协调器。它是一个小型实用程序(体积小但功能强大),随 Windows 操作系统一起提供。它允许在同一台或多台服务器的应用程序域之间管理和维护事务。它具有丰富的 API 集,可以从 .NET Framework API 访问。
简而言之,它允许我们在服务器之间进行事务。
Michele Leroux Bustamante 在 MSDN 上的这个精彩视频深入介绍了 MSDTC 及其实际用法。
SQL Server 中的事务
SQL Server 在 T-SQL 中拥有丰富的事务管理集,可以使用它来管理事务的级别和其他事项。 CodeProject 上的这篇文章描述了在 SQL Server 中使用事务。
此处描述的技术允许我们在给定数据库的表之间管理事务。
.NET 中的事务
.NET 类库使用 MSDTC 提供了事务管理功能。 MSDN 上的这篇文章使用 TransactionScope
类描述了机制。
本文描述的技术可用于管理给定应用程序域内数据库之间的事务。当然,我没有考虑数据库运行在单独的应用程序域中的事实。
WCF 中的事务
WCF 具有事务管理功能,允许在应用程序域之间进行事务管理。 Michele Leroux Bustamante 的 视频教程详细描述了在 WCF 中使用事务。它还包含有关 .NET 事务的代码片段。
关于事务的一些最佳实践
有了这些基础知识,我们就可以开始讨论有关最佳实践的细节,即事务应该在哪里启动以及如何管理它们。
规则一(也是唯一规则):尽可能晚地启动事务
事务应尽可能晚地在应用程序生命周期中启动。考虑以下示例。
如果需要在单个存储过程中更新多个表,则应在存储过程中管理事务。但是,如果要更新多个数据库,则应在 .NET 组件中管理事务。
事务应尽可能晚地启动,因为它提高了可靠性、性能并提供了更好的故障转移支持。事务启动得越晚,发生死锁的可能性就越小。
规则二(从没有唯一规则):每个参与的组件都应管理自己的事务
这条规则存在争议。一种观点认为只有一个主组件应该管理所有事务,但我认为每个参与的组件都应该管理自己的事务。换句话说,假设一个 .NET 组件调用多个存储过程,那么每个存储过程。
建议这样做,以便每个参与的组件都可以扩展并独立调用。嵌套事务具有更好的可靠性。

历史
- 2009 年 10 月 11 日:初始帖子