

# RDS for SQL Server 中的 Microsoft 分布式事务处理协调器支持
<a name="Appendix.SQLServer.Options.MSDTC"></a>

*分布式事务*是涉及两个或多个网络主机的数据库事务。RDS for SQL Server 支持在主机之间存在分布式事务，其中一个主机可以是以下之一：
+ RDS for SQL Server DB 实例
+ 本地 SQL Server 主机
+ 安装了 SQL Server 的 Amazon EC2 主机
+ 具有支持分布式事务的数据库引擎的任何其他 EC2 主机或 RDS 数据库实例

在 RDS 中，从 SQL Server 2012（版本 11.00.5058.0.v1 及更高版本）开始，RDS for SQL Server 的所有版本都支持分布式事务。该支持使用 Microsoft 分布式事务处理协调器 (MSDTC) 提供。有关 MSDTC 的详细信息，请参阅 Microsoft 文档中的[分布式事务处理协调器](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms684146(v=vs.85))。

**Contents**
+ [限制](#Appendix.SQLServer.Options.MSDTC.Limitations)
+ [启用 MSDTC](Appendix.SQLServer.Options.MSDTC.Enabling.md)
  + [为 MSDTC 创建选项组](Appendix.SQLServer.Options.MSDTC.Enabling.md#Appendix.SQLServer.Options.MSDTC.OptionGroup)
  + [将 MSDTC 选项添加到选项组](Appendix.SQLServer.Options.MSDTC.Enabling.md#Appendix.SQLServer.Options.MSDTC.Add)
  + [为 MSDTC 创建参数组](Appendix.SQLServer.Options.MSDTC.Enabling.md#MSDTC.CreateParamGroup)
  + [修改 MSDTC 的参数](Appendix.SQLServer.Options.MSDTC.Enabling.md#ModifyParam.MSDTC)
  + [将选项组和参数组与数据库实例关联](Appendix.SQLServer.Options.MSDTC.Enabling.md#MSDTC.Apply)
  + [修改 MSDTC 选项](Appendix.SQLServer.Options.MSDTC.Enabling.md#Appendix.SQLServer.Options.MSDTC.Modify)
+ [使用事务](#Appendix.SQLServer.Options.MSDTC.Using)
  + [使用分布式事务](#Appendix.SQLServer.Options.MSDTC.UsingXA)
  + [使用 XA 事务](#MSDTC.XA)
  + [使用事务跟踪](#MSDTC.Tracing)
+ [禁用 MSDTC](Appendix.SQLServer.Options.MSDTC.Disable.md)
+ [RDS for SQL Server 的 MSDTC 故障排除](Appendix.SQLServer.Options.MSDTC.Troubleshooting.md)

## 限制
<a name="Appendix.SQLServer.Options.MSDTC.Limitations"></a>

以下限制适用于在 RDS for SQL Server 上使用 MSDTC：
+ 使用 SQL Server 数据库镜像的实例上不支持 MSDTC。有关详细信息，请参阅[事务 – 可用性组和数据库镜像](https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/transactions-always-on-availability-and-database-mirroring?view=sql-server-ver15#non-support-for-distributed-transactions)。
+ `in-doubt xact resolution` 参数必须设置为 1 或 2。有关更多信息，请参阅 [修改 MSDTC 的参数](Appendix.SQLServer.Options.MSDTC.Enabling.md#ModifyParam.MSDTC)。
+ MSDTC 要求参与分布式事务的所有主机都可以使用其主机名进行解析。RDS 会自动为加入域的实例维护此功能。但是，对于独立实例，请确保手动配置 DNS 服务器。
+ SQL Server 2017 版本 14.00.3223.3 及更高版本和 SQL Server 2019 支持 Java Database Connectivity (JDBC) XA 事务。
+ 依赖于 RDS 实例上的客户端动态链接库 (DLL) 的分布式事务不受支持。
+ 不支持使用自定义 XA 动态链接库。

## 使用事务
<a name="Appendix.SQLServer.Options.MSDTC.Using"></a>

### 使用分布式事务
<a name="Appendix.SQLServer.Options.MSDTC.UsingXA"></a>

在 Amazon RDS for SQL Server 中，您可以按照与本地运行分布式事务相同的方式运行分布式事务：
+ 使用 .NET 框架 `System.Transactions` 可提升事务，它通过将分布式事务的创建推迟到在需要时进行，以此优化分布式事务。

  在这种情况下，提升是自动的，不需要您进行任何干预。如果事务中只有一个资源管理器，则不执行任何提升。有关隐式事务范围的更多信息，请参阅 Microsoft 文档中的[使用事务范围实施隐式事务](https://docs.microsoft.com/en-us/dotnet/framework/data/transactions/implementing-an-implicit-transaction-using-transaction-scope)。

  以下 .NET 实施支持可提升事务：
  + 从 ADO.NET 2.0 开始，`System.Data.SqlClient` 支持 SQL Server 的可提升事务。有关更多信息，请参阅 Microsoft 文档中的 [System.Transactions 与 SQL Server 的集成](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/system-transactions-integration-with-sql-server)。
  + ODP.NET 支持 `System.Transactions`。将为在 `TransactionsScope` 范围内与 Oracle Database 11g 发行版 1（版本 11.1）及更高版本建立的第一个连接创建一个本地事务。建立第二个连接时，此事务将自动提升为分布式事务。有关 ODP.NET 中的分布式事务支持的更多信息，请参阅 Microsoft 文档中的 [Microsoft 分布式事务处理协调器集成](https://docs.oracle.com/en/database/oracle/oracle-data-access-components/18.3/ntmts/using-mts-with-oracledb.html)。
+ 使用 `BEGIN DISTRIBUTED TRANSACTION` 语句。有关更多信息，请参阅 Microsoft 文档中的 [BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)](https://docs.microsoft.com/en-us/sql/t-sql/language-elements/begin-distributed-transaction-transact-sql)。

### 使用 XA 事务
<a name="MSDTC.XA"></a>

从 RDS for SQL Server 2017 版本 14.00.3223.3 开始，您可以使用 JDBC 控制分布式事务。当您在 `MSDTC` 选项将 `Enable XA` 选项设置为 `true` 时，RDS 会自动启用 JDBC 事务并授予 `SqlJDBCXAUser` 角色给 `guest` 用户。这允许通过 JDBC 执行分布式事务。有关包括代码示例在内的更多信息，请参阅 Microsoft 文档中的[了解 XA 事务](https://docs.microsoft.com/en-us/sql/connect/jdbc/understanding-xa-transactions)。

### 使用事务跟踪
<a name="MSDTC.Tracing"></a>

RDS 支持控制 MSDTC 事务跟踪并从 RDS 数据库实例下载它们以进行故障排除。您可以通过运行以下 RDS 存储过程来控制事务跟踪会话。

```
exec msdb.dbo.rds_msdtc_transaction_tracing 'trace_action',
[@traceall='0|1'],
[@traceaborted='0|1'],
[@tracelong='0|1'];
```

以下参数是必需参数：
+ `trace_action` – 跟踪操作。它可以是 `START`、`STOP` 或 `STATUS`。

以下参数为可选参数：
+ `@traceall` – 设置为 1 可跟踪所有分布式事务。默认值为 0。
+ `@traceaborted` – 设置为 1 可跟踪已取消的分布式事务。默认值为 0。
+ `@tracelong` – 设置为 1 可跟踪长时间运行的分布式事务。默认值为 0。

**Example 启动跟踪操作示例**  
要启动新的事务跟踪会话，请运行以下示例语句。  

```
exec msdb.dbo.rds_msdtc_transaction_tracing 'START',
@traceall='0',
@traceaborted='1',
@tracelong='1';
```
一次只能有一个活动的事务跟踪会话。如果在有跟踪会话处于活动状态时发出了新的跟踪会话 `START` 命令，则返回错误，并且活动的跟踪会话保持不变。

**Example 停止跟踪操作示例**  
要停止事务跟踪会话，请运行以下语句。  

```
exec msdb.dbo.rds_msdtc_transaction_tracing 'STOP'
```
此语句停止活动的事务跟踪会话，并将事务跟踪数据保存到 RDS 数据库实例上的日志目录中。输出的第一行包含整体结果，后面的行表示操作的详细信息。  
以下是成功跟踪会话停止的示例。  

```
OK: Trace session has been successfully stopped.
Setting log file to: D:\rdsdbdata\MSDTC\Trace\dtctrace.log
Examining D:\rdsdbdata\MSDTC\Trace\msdtctr.mof for message formats,  8 found.
Searching for TMF files on path: (null)
Logfile D:\rdsdbdata\MSDTC\Trace\dtctrace.log:
 OS version    10.0.14393  (Currently running on 6.2.9200)
 Start Time    <timestamp>
 End Time      <timestamp>
 Timezone is   @tzres.dll,-932 (Bias is 0mins)
 BufferSize            16384 B
 Maximum File Size     10 MB
 Buffers  Written      Not set (Logger may not have been stopped).
 Logger Mode Settings (11000002) ( circular paged
 ProcessorCount         1 
Processing completed   Buffers: 1, Events: 3, EventsLost: 0 :: Format Errors: 0, Unknowns: 3
Event traces dumped to d:\rdsdbdata\Log\msdtc_<timestamp>.log
```
您可以使用详细信息查询生成的日志文件的名称。有关从 RDS 数据库实例下载日志文件的更多信息，请参阅 [监控 Amazon RDS 日志文件](USER_LogAccess.md)。  
跟踪会话日志在实例上保留 35 天。任何较旧的跟踪会话日志都会自动删除。

**Example 状态跟踪操作示例**  
要跟踪事务跟踪会话的状态，请运行以下语句。  

```
exec msdb.dbo.rds_msdtc_transaction_tracing 'STATUS'
```
此语句在规则集中将以下内容作为单独的行输出。  

```
OK
SessionStatus: <Started|Stopped>
TraceAll: <True|False>
TraceAborted: <True|False>
TraceLongLived: <True|False>
```
第一行表示操作的整体结果：`OK` 或 `ERROR`，并带有详细信息（如果适用）。后面的行指示有关跟踪会话状态的详细信息：  
+ `SessionStatus` 的值可以是以下值之一：
  + `Started`，有跟踪会话正在运行时。
  + `Stopped`，没有跟踪会话正在运行时。
+ 跟踪会话标志可以是 `True` 或 `False`，具体取决于它们在 `START` 命令中的设置方式。