11.3.2. 关于单阶段提交 LRCO 优化(1PC)
单阶段提交(1PC)
尽管交易时常遇到 2 阶段提交协议(2PC),但在某些情况下不要求或无法满足这两个阶段。在这些情况下,您可以使用单一阶段提交(1PC)协议。当只有一个 XA 或非 XA 资源是全球交易的一部分时,使用单一阶段commnit 协议。
准备阶段通常会锁定资源,直到第二阶段处理为止。单阶段提交意味着跳过准备阶段,并且仅对资源处理提交。如果没有指定,则当全局交易仅包含一个参与者时,会自动使用单阶段提交优化。
最后资源提交优化(LRCO)
在非 XA 数据源参与 XA 事务的情况下,使用名为 Last Resource Commit Optimization(LRCO)的优化。虽然此协议允许大多数事务正常完成,但某些类型的错误可能会导致交易结果不一致。因此,仅将此方法用作最后的手段。
非 XA 资源在准备阶段结束时处理,并尝试进行提交。如果提交成功,则会写入事务日志,其余的资源将进入提交阶段。如果最后一个资源未能提交,则会回滚事务。
当在事务中使用一个本地 TX 数据源时,LRCO 会自动应用到它。
在以前的版本中,在 XA 事务中添加非 XA 资源是通过 LRCO 方法实现的。但是 LRCO 中存在一个故障窗口。使用 LRCO 方法将非 XA 资源添加到 XA 事务的步骤如下:
- 准备 XA 事务。
- 提交 LRCO.
- 写入事务日志。
- 提交 XA 事务。
如果流程在步骤 2 和步骤 3 间崩溃,这可能会导致数据不一致,且您无法提交 XA 事务。数据不一致的原因是提交了 LRCO 非 XA 资源,但没有记录有关准备 XA 资源的信息。恢复管理器将在服务器启动后回滚资源。提交标记资源(CMR)消除了此限制,并允许将非 XA 资源可靠地加入 XA 事务。
CMR 属于 LRCO 优化的特殊情形,仅用于数据源。它并不适用于所有非 XA 资源。
11.3.2.1. 提交可标记资源
概述
使用 Commit Markable Resource(CMR)接口配置资源管理器的访问权限可确保在 XA(2PC)事务中可靠地加入非 XA 数据源。LRCO 算法的实施使非 XA 资源完全可以恢复。
要配置 CMR,您必须:
- 在数据库中创建表。
- 启用数据源可连接。
-
添加对
事务
子系统的引用。
在数据库中创建表
事务只能包含一个 CMR 资源。您可以使用类似以下示例的 SQL 创建表。
SELECT xid,actionuid FROM _tableName_ WHERE transactionManagerID IN (String[]) DELETE FROM _tableName_ WHERE xid IN (byte[[]]) INSERT INTO _tableName_ (xid, transactionManagerID, actionuid) VALUES (byte[],String,byte[])
以下是用于为各种数据库管理系统创建表的 SQL 语法示例。
示例:Sybase Create Table Syntax
CREATE TABLE xids (xid varbinary(144), transactionManagerID varchar(64), actionuid varbinary(28))
示例:甲骨文创建表语法
CREATE TABLE xids (xid RAW(144), transactionManagerID varchar(64), actionuid RAW(28)) CREATE UNIQUE INDEX index_xid ON xids (xid)
示例:IBM 创建表语法
CREATE TABLE xids (xid VARCHAR(255) for bit data not null, transactionManagerID varchar(64), actionuid VARCHAR(255) for bit data not null) CREATE UNIQUE INDEX index_xid ON xids (xid)
示例:SQL Server Create Table Syntax
CREATE TABLE xids (xid varbinary(144), transactionManagerID varchar(64), actionuid varbinary(28)) CREATE UNIQUE INDEX index_xid ON xids (xid)
示例:PostgreSQL 创建表语法
CREATE TABLE xids (xid bytea, transactionManagerID varchar(64), actionuid bytea) CREATE UNIQUE INDEX index_xid ON xids (xid)
示例:MariaDB 创建表语法
CREATE TABLE xids (xid BINARY(144), transactionManagerID varchar(64), actionuid BINARY(28)) CREATE UNIQUE INDEX index_xid ON xids (xid)
示例:Myntax(Myntax)
CREATE TABLE xids (xid VARCHAR(255), transactionManagerID varchar(64), actionuid VARCHAR(255)) CREATE UNIQUE INDEX index_xid ON xids (xid)
启用数据源可连接
默认情况下,sources 禁用 CMR 功能。若要启用它,您必须创建或修改数据源配置,并确保 connectable
属性设为 true
。以下是服务器 XML 配置文件的 datasources 部分的示例:
<datasource enabled="true" jndi-name="java:jboss/datasources/ConnectableDS" pool-name="ConnectableDS" jta="true" use-java-context="true" connectable="true"/>
这个功能不适用于 XA 数据源。
您还可以使用管理 CLI 启用资源管理器作为 CMR,如下所示:
/subsystem=datasources/data-source=ConnectableDS:add(enabled="true", jndi-name="java:jboss/datasources/ConnectableDS", jta="true", use-java-context="true", connectable="true", connection-url="validConnectionURL", exception-sorter-class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLExceptionSorter", driver-name="mssql")
此命令会在服务器配置文件的 datasources
部分中生成以下 XML:
<datasource jta="true" jndi-name="java:jboss/datasources/ConnectableDS" pool-name="ConnectableDS" enabled="true" use-java-context="true" connectable="true"> <connection-url>validConnectionURL</connection-url> <driver>mssql</driver> <validation> <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLExceptionSorter"/> </validation> </datasource>
数据源必须定义一个有效的驱动程序。上例使用 mssql
作为 driver-name
,但 mssql
驱动程序不存在。详情请参阅 JBoss EAP 配置指南中的 MySQL 数据源示例。
在数据源配置 中使用 exception-sorter-class-name
参数。详情请参阅 JBoss EAP 配置指南中的数据源配置示例 。
更新现有资源以使用新的 CMR 功能
如果您只需要更新现有数据源以使用 CMR 功能,只需修改 connectable
属性:
/subsystem=datasources/data-source=ConnectableDS:write-attribute(name=connectable,value=true)
添加对事务子系统的引用
transaction 子系统
标识 CMR 能够通过进入 transaction 子系统
配置部分的条目实现的数据源,如下所示:
<subsystem xmlns="urn:jboss:domain:transactions:5.0"> ... <commit-markable-resources> <commit-markable-resource jndi-name="java:jboss/datasources/ConnectableDS"> <xid-location name="xids" batch-size="100" immediate-cleanup="false"/> </commit-markable-resource> ... </commit-markable-resources> </subsystem>
使用管理 CLI 可以实现相同的结果:
/subsystem=transactions/commit-markable-resource=java\:jboss\/datasources\/ConnectableDS/:add(batch-size=100,immediate-cleanup=false,name=xids)
您必须在 事务
子系统中添加 CMR 引用后重新启动服务器。