更新时间:2023-06-14 14:04
为了实现分布式事务,需要使用下面将介绍的两阶段提交协议。 * 阶段一:开始向事务涉及到的全部资源发送提交前信息。此时,事务涉及到的资源还有最后一次机会来异常结束事务。如果任意一个资源决定异常结束事务,则整个事务取消,不会进行资源的更新。否则,事务将正常执行,除非发生灾难性的失败。为了防止会发生灾难性的失败,所有资源的更新都会写入到日志中。这些日志是永久性的,因此,这些日志会幸免于难并且在失败之后可以重新对所有资源进行更新。 * 阶段二:只在阶段一没有异常结束的时候才会发生。此时,所有能被定位和单独控制的资源管理器都将开始执行真正的数据更新。 在分布式事务两阶段提交协议中,有一个主事务管理器负责充当分布式事务协调器的角色。事务协调器负责整个事务并使之与网络中的其他事务管理器协同工作。 为了实现分布式事务,必须使用一种协议在分布式事务的各个参与者之间传递事务上下文信息,IIOP便是这种协议。这就要求不同开发商开发的事务参与者必须支持一种标准协议,才能实现分布式的事务。
分布式事务处理 (TP) 系统旨在协助在分布式环境中跨异类的事务识别资源的事务。在分布式 TP 系统的支持下,应用程序可以将不同的活动合并为一个事务性单元,这些活动包括从“消息队列”队列检索消息、将消息存储在 Microsoft SQL Server 数据库中、将所有现有的消息引用从 Oracle Server 数据库中移除,等等。因为分布式事务跨多个数据库资源,故强制 ACID 属性维护所有资源上的数据一致性是很重要的。
在 Transact-SQL 中启动的分布式事务的结构相对比较简单:
1. Transact-SQL脚本或应用程序连接执行启动分布式事务的 Transact-SQL 语句。
2. 执行该语句的 Microsoft® SQL Server™ 成为事务中的主控服务器。
3. 然后脚本或应用程序对链接的服务器执行分布式查询,或对远程服务器执行远程存储过程。
4. 当执行了分布式查询或远程过程调用后,主控服务器将自动调用 MS DTC 以便登记分布式事务中链接的服务器和远程服务器。
5. 当脚本或应用程序发出 COMMIT 或 ROLLBACK 语句时,主控 SQL Server 将调用 MS DTC 管理两阶段提交过程,或者通知链接的服务器和远程服务器回滚其事务。
控制分布式事务的 Transact-SQL 语句很少,因为多数工作都由 Microsoft® SQL Server™ 和 MS DTC 在内部完成。Transact-SQL 脚本或应用程序中所需的 Transact-SQL 语句只须:
●启动分布式事务。
●对链接的服务器执行分布式查询,或对远程服务器执行远程过程调用。
●调用标准 Transact-SQL COMMIT TRANSACTION、COMMIT WORK、ROLLBACK TRANSACTION 或 ROLLBACK WORK 语句完成事务。
●对于任意一个 Transact-SQL 分布式事务,处理 Transact-SQL脚本或连接的 SQL Server 将自动调用 MS DTC 以协调事务的提交或回滚。
REMOTE_PROC_TRANSACTIONS 选项是一个兼容性选项,只影响对使用sp_addserver定义的远程服务器所进行的远程存储过程调用。有关远程存储过程的更多信息,请参见远程存储过程构架。该选项不适用于在使用sp_addlinkedserver定义的链接服务器上执行存储过程的分布式查询。有关分布式查询的更多信息,请参见分布式查询。
用 OLE DB、ODBC、ADO或 DB-Library 编写的应用程序使用 Transact-SQL 分布式事务的方法可以是,发出 Transact-SQL 语句启动和停止 Transact-SQL 分布式事务。但是,OLE DB 和 ODBC 还包含在 API 层对管理分布式事务的支持。OLE DB 和 ODBC 应用程序可以使用这些 API 函数管理包括其它 COM资源管理器(支持 MS DTC 事务而非 Microsoft® SQL Server™)的分布式事务。它们也可以使用 API 函数获取对包括多个 SQL Server 的分布式事务边界的更多控制。
ODBC 分布式事务
通过将连接特性 SQL_ATTR_AUTOCOMMIT 设置为 SQL_AUTOCOMMIT_OFF,然后调用 ODBCSQLEndTran函数提交或回滚每个事务,可以控制 ODBC API 层的本地事务。不要使用这些函数管理 ODBC 应用程序中的分布式事务。而应该使用 MS DTC COM 方法:
● 调用 DtcGetTransactionManager 连接到 MS DTC。
● 调用 ITransactionDispenser::BeginTransaction 启动分布式事务并获取事务对象。
● 对每个参与分布式事务的 ODBC 连接,调用 ODBC 函数 SQLSetConnectAttr,其中 fOption 设置为 SQL_COPT_SS_ENLIST_IN_DTC,vParam 控制来自 ITransactionDispenser::BeginTransaction 的事务对象的地址。
● 当事务完成时,对于从 ITransactionDispenser::BeginTransaction 获得的事务对象,不要调用 ODBC SQLEndTran 函数,应该调用 ITransaction::Commit 或 ITransaction::Rollback 方法。
OLE DB 分布式事务
控制 OLE DB 中的分布式事务的方法与控制本地事务的方法相似。若要控制本地事务,则 OLE DB 的使用者应该:
● 使用 ITransactionLocal::StartTransaction 方法启动本地事务,并获得事务对象。
● 然后使用者在从 ITransactionLocal::StartTransaction 获得的事务对象上,调用 ITransaction::Commit 或 ITransaction::Rollback 方法。
若要控制分布式事务,使用者应该: ● 调用 DtcGetTransactionManager 连接到 MS DTC。
● 调用 ITransactionDispenser::BeginTransaction 启动分布式事务,并获得事务对象。
● 对每个参与分布式事务的连接,调用分布式事务对象的 ITransactionJoin 接口。
● 调用分布式事务对象的 ITransaction::Commit 或 ITransaction::Rollback 方法,完成该事务。
Microsoft® SQL Server™ 允许创建与称为链接服务器的 OLE DB 数据源的链接。在链接到 OLE DB 数据源之后,可以:
● 从 OLE DB 数据源引用行集,作为 Transact-SQL 语句中的表。
● 将命令传递给 OLE DB 数据源,并包含结果行集,作为 Transact-SQL 语句中的表。
每个分布式查询都可以引用多个链接的服务器,而且可以对每个链接的服务器分别执行更新或读取操作。单个分布式查询可以对某些链接的服务器执行读取操作,并且对其它链接的服务器执行更新操作。通常情况下,每当某个事务可能更新多个链接服务器中的数据时,Microsoft SQL Server 都要求相应的 OLE DB 提供程序支持分布式事务。因此,链接服务器上所支持的查询类型取决于 OLE DB 提供程序中对事务的支持级别。OLE DB 为事务管理定义了两个可选的接口:
● ITransactionLocal 支持 OLE DB数据源中的本地事务。
● ITransactionJoin 允许提供程序联结包含其它资源管理器的分布式事务。
● 所有支持 ITransactionJoin 的提供程序也都支持 ITransactionLocal。
如果在连接是自动提交模式时执行分布式查询,则应用以下规则:
● 对于不支持 ItransactionLocal 的提供程序,只允许执行读取操作。
● 对于支持 ITransactionLocal 的提供程序,允许执行所有更新操作。
● 主控 SQL Server 会自动调用每个参与更新操作的链接的服务器中的 ITransactionLocal,以启动本地事务,并在语句执行成功时提交或在语句执行失败时回滚。
如果分布式查询是针对分布式分区视图或者是在连接为显式或隐性事务时执行,则应用下列规则:
● 对于不支持 ITransactionJoin 的提供程序,只允许执行读取操作。不支持任何事务或只支持 ITransactionLocal 的提供程序不能参与更新操作。
● 如果 SET XACT_ABORT 设置为 ON,则对于支持 ITransactionJoin 的任意提供程序都允许执行所有的更新操作。主控 SQL Server 会自动调用每个参与更新操作的链接服务器中的 ITransactionJoin,以便在分布式事务中登记该服务器。然后当主控服务器表示要提交或回滚事务时,MS DTC 将提交或者回滚。
● 如果 SET XACT_ABORT 设置为 OFF,则链接服务器还必须支持嵌套事务,才能对其执行更新操作。当会话已经有一个现有事务时,如果提供程序支持调用 ITransactionLocal::StartTransaction,则支持嵌套事务。这使 SQL Server 得以回滚分布式查询中的单个语句,而不是回滚整个事务。
上述规则意味着提供程序的下列限制不支持嵌套事务:仅在 XACT_ABORT 选项设置为 ON 时,分布式事务中才允许更新操作。