11.3. 事务优化
11.3.1. 交易优化概述 复制链接链接已复制到粘贴板!
JBoss EAP 交易经理(TM)包括多个优化功能,供您的应用利用:
优化有助于在特定情况下增强两阶段提交协议。通常,TM 会启动全局事务,该事务通过两阶段提交。但在某些情况下,当您优化这些事务时,TM 不需要进行完整的 2 阶段提交,因此进程速度更快。
下面详细介绍了 TM 使用的不同优化。
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[])
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 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)
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)
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)
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)
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)
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)
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"/>
<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")
/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:
数据源必须定义一个有效的驱动程序。上例使用 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)
/subsystem=datasources/data-source=ConnectableDS:write-attribute(name=connectable,value=true)
添加对事务子系统的引用
transaction 子系统 标识 CMR 能够通过进入 transaction 子系统 配置部分的条目实现的数据源,如下所示:
使用管理 CLI 可以实现相同的结果:
/subsystem=transactions/commit-markable-resource=java\:jboss\/datasources\/ConnectableDS/:add(batch-size=100,immediate-cleanup=false,name=xids)
/subsystem=transactions/commit-markable-resource=java\:jboss\/datasources\/ConnectableDS/:add(batch-size=100,immediate-cleanup=false,name=xids)
您必须在 事务 子系统中添加 CMR 引用后重新启动服务器。
11.3.3. 关于presumed-Abort Optimization 复制链接链接已复制到粘贴板!
如果交易要回滚,它可以在本地记录此信息并通知所有参与方。该通知只是礼貌,对交易结果没有影响。联系了所有参与者后,可以删除有关交易的信息。
如果随后发生交易状态请求,则不会提供任何信息。在这种情况下,请求者假定事务已中止并回滚。这种假定的优化意味着,在决定提交交易之前,不需要使参与者的任何信息永久保留,因为在此之前的任何故障都将被视为交易的中止。
11.3.4. 关于只读优化 复制链接链接已复制到粘贴板!
当要求参与者准备时,可以向协调者表明其在交易期间没有修改任何数据。不需要向这类参与者告知交易结果,因为参与者的承诺不会影响交易。提交协议的第二阶段中可以省略该只读参与者。