事务选项
使用管理控制台配置 JDBC 数据源时,WebLogic Server 会根据 JDBC 驱动程序的类型自动选择特定的事务选项:
对于 XA 驱动程序,系统会自动选择用于全局事务处理的两阶段提交协议。对于非 XA 驱动程序,将按照定义支持本地事务,并且 WebLogic Server 会提供以下选项支持全局事务:(在默认情况下处于选中状态)如果要在全局事务中使用来自数据源的连接,则选中此选项,即使未选择 XA 驱动程序也是如此。有关详细信息,请参阅使用非 XA JDBC 驱动程序启用对全局事务的支持。选中“支持全局事务”时,还必须为 WebLogic Server 选择在处理全局事务时要用于事务分支的协议:记录上一个资源:使用此选项,会将使用连接的事务分支作为事务中最后的资源进行处理,并将其作为本地事务进行处理。两阶段提交(two-phase commit,简称 2PC)的提交记录会插入资源自身的表中,且此结果确定了全局事务准备阶段的成功或失败。与“仿真两阶段提交”相比,此选项具有一些性能优势和更高的数据安全性,但它具有某些限制。请参阅了解“记录上一个资源”选项。注意: 多数据源使用的数据源不支持“记录上一个资源”。 仿真两阶段提交:使用此选项,使用连接的事务分支始终返回事务准备阶段的成功信息。此选项提供了性能优势,但在某些失败情况下也存在破坏数据的风险。只有在应用程序可允许出现试探性情况时才能选择此选项。一阶段提交:(在默认情况下处于选中状态)使用此选项,来自数据源的连接只能是全局事务的唯一参与者,并且该事务是使用一阶段提交优化完成的。如果多个资源参与该事务,则事务管理器在 1PC 资源上调用XAResource.prepare
时会引发异常。
使用非 XA JDBC 驱动程序启用对全局事务的支持
如果在应用程序中使用全局事务,则应使用 XA JDBC 驱动程序在 JDBC 数据源中创建数据库连接。如果某个 XA 驱动程序不可用于您的数据库,或者您不希望使用 XA 驱动程序,那么您应在数据源中启用对全局事务的支持。如果应用程序满足以下任何一个条件,则也应启用对全局事务的支持:
了解“记录上一个资源”选项
WebLogic Server 通过 JDBC 数据源支持“记录上一个资源”(Logging Last Resource,简称 LLR)事务优化。LLR 是一个性能增强选项,使用该选项可使一个非 XA 资源能够使用与 XA 同样的 ACID 保证参与全局事务。LLR 是“上一个代理优化”的改进结果。它与“上一个代理优化”不同,因为它对于事务而言是安全的。LLR 资源对其事务工作使用本地事务。WebLogic Server 事务管理器准备事务中的所有其他资源,然后根据 LLR 资源本地事务的结果确定全局事务的提交决定。
当为 LLR 配置的数据源中的连接参与两阶段提交 (2PC) 全局事务时,WebLogic Server 事务管理器会通过以下方式完成事务:
LLR 数据源的编程注意事项和限制
可按照使用来自任何其他数据源的 JDBC 连接的方式,在应用程序中使用来自启用了 LLR 的数据源的 JDBC 连接:在开始某个事务之后,在 JNDI 树中查找数据源,然后请求一个来自该数据源的连接。但是,使用 LLR 优化时,WebLogic Server 会在内部管理连接请求,并以不同于在 XA 事务中使用的处理方式来处理事务处理。
使用 LLR 数据源进行编程时,必须在调用 LLR 数据源的 getConnection 之前启动全局事务。如果在启动全局事务之前调用 getConnection,则会使对该连接的所有操作都处于全局事务之外。仅对每个事务保留一个内部 JDBC LLR 连接,并且该连接将用于整个事务处理。保留的连接始终承载在该事务的协调器服务器上。请确保该数据源已定位到协调服务器或群集。对于该事务中来自同名数据源的其他 JDBC 连接请求,操作会路由到来自原始连接请求的已保留连接,即使后续请求是在该数据源的其他实例(即部署在与为第一个请求提供连接的原始数据源所在服务器不同的服务器上的数据源)上做出的,也是如此。请注意以下内容:只有单个 LLR 数据源的实例可以参与某个特定事务。单个 LLR 数据源可在多个 WebLogic 服务器上具有实例,如果两个数据源具有相同的已配置名称,则这两个数据源会被认为是相同的。如果检测到多个 LLR 数据源实例,并且它们不是同一数据源的实例,则事务管理器会回滚事务。实现weblogic.transaction.nonxa.NonXAResource
接口的资源适配器(连接器)不能参与 LLR 资源也同时参与的全局事务,因为二者都必须是事务中的最后一个资源。如果两种资源类型都参与同一个事务,则在检测到此冲突时,事务的commit()
方法会引发javax.transaction.RollbackException
。由于 LLR 连接对于数据库处理使用单独的本地事务,因此,在 LLR 处理过程中,使用 XA 连接对同一数据库进行的任何更改(和进行的任何锁定)都将不可见,即使所有的处理都发生在同一全局事务中,也是如此。在某些情况下,这可能会在数据库中引起死锁。在单个全局事务中不应在同一数据库中混合 XA 和 LLR 处理。来自某个 LLR 数据源的连接不能参与由外部事务管理器协调的事务,如由远程对象请求代理或由 Tuxedo 启动的事务。全局事务不能跨至另一个包含了与某个 LLR 数据源同名的数据源的旧式域。对于 JDBC LLR 2PC 事务,如果事务数据太大,无法装入 LLR 表中,则事务将会失败,并在提交期间生成一个回滚异常。如果在事务处理过程中,您的应用程序添加了许多事务属性,则会发生上述情况。如果发生了上述情况,那么,数据库管理员可手工创建一个具有更大的列的表。
LLR 数据源的管理注意事项和限制
配置启用了 LLR 的 JDBC 数据源时,请考虑以下要求和限制:
对于每个服务器,都有一个 LLR 表:如果在引导期间数据库处于关闭状态或 LLR 表不可访问,则服务器将不会进行引导。多个服务器不得共享同一个 LLR 表。引导会进行检查,以确保域和服务器名称与创建表时存储在表中的域和服务器名称相匹配。如果 WebLogic Server 检测到多个服务器正在共享同一个 LLR 表,则 WebLogic Server 将关闭一个或多个服务器。LLR 支持服务器迁移和事务恢复服务迁移。要使用事务恢复服务迁移,请确保每个 LLR 资源都会定位到群集或群集中的候选服务器组。请参阅“为发生故障的群集服务器恢复事务”。在 JDBC 应用程序模块中不允许使用 LLR 事务选项。多数据源使用的数据源中不支持使用 LLR 事务选项。如果在某个 LLR 数据源上使用了凭据映射,则所有映射的用户都必须具有对该 LLR 表的写权限。不能使用 JDBC XA 驱动程序在 JDBC LLR 数据源中创建数据库连接。如果 JDBC LLR 数据源中使用的 JDBC 驱动程序支持 XA,则会记录一条警告消息,并且数据源会作为完全的 XA 资源(而不是作为 LLR 资源)参与事务。会在“NonXAResource”下跟踪 LLR 资源的事务统计信息。
了解“仿真两阶段提交”事务选项
如果需要使用某个 JDBC 数据源来支持分布式事务,但没有符合 XA 标准的驱动程序可供您的 DBMS 使用,则可对某个数据源的“非 XA 驱动程序”选项选择“仿真两阶段提交”,以便对来自该数据源的连接参与的事务仿真两阶段提交。此选项是“常规”选项卡(可通过依次选择“JDBC 数据源”“配置”
“常规”选项卡来访问该选项卡)上的高级选项。
对“非 XA 驱动程序”选项选择“仿真两阶段提交”(EnableTwoPhaseCommit
设置为true
)时,非 XA JDBC 资源总是会在XAResource.prepare
() 方法调用期间返回XA_OK
。资源会尝试提交或回滚其本地事务以响应后续的XAResource.commit
() 或XAResource.rollback
() 调用。如果资源提交或回滚失败,则会导致一个试探性错误。应用程序数据可能会由于试探性失败而处于不一致状态。
未在控制台中对“非 XA 驱动程序”选项选择“仿真两阶段提交”(EnableTwoPhaseCommit
设置为false
)时,非 XA JDBC 资源会导致XAResource.prepare
() 失败。当仅有一个资源参与事务时,一阶段优化将跳过XAResource.prepare
(),并且在大多数情况下,事务会成功提交。
注意: | 对“非 XA 驱动程序”选项选择“仿真两阶段提交”时,会存在破坏数据完整性的风险。BEA 建议使用符合 XA 标准的 JDBC 驱动程序或“记录上一个资源”选项(而不是使用“仿真两阶段提交”选项)。请确保在启用此选项之前考虑了这些风险。 |
该非 XA JDBC 驱动程序支持通常称为“JTS 驱动程序”,因为 WebLogic Server 在内部使用 WebLogic JTS 驱动程序以支持该功能。
使用非 XA 驱动程序仿真两阶段提交时的限制和风险
WebLogic Server 使用“仿真两阶段提交”数据源事务选项支持非 XA JDBC 资源参与全局事务,但会存在一些在设计应用程序(以使用这样的数据源)时必须考虑的限制。因为非 XA 驱动程序不符合 XA/2PC 合同,并且仅支持一阶段提交和回滚操作,所以 WebLogic Server(通过 JTS 驱动程序)必须进行妥协以允许资源参与由事务管理器控制的某个事务。
在对“非 XA 驱动程序”选项使用“仿真两阶段提交”之前,请考虑以下限制和风险:
试探性完成和数据不一致
对非 XA 资源选择“仿真两阶段提交”(enableTwoPhaseCommit = true
) 时,非 XA 资源的事务准备阶段总是会成功。因此,非 XA 资源没有真正地参与两阶段提交 (2PC) 协议,并且容易失败。如果在准备阶段之后,在非 XA 资源中发生故障,则非 XA 资源可能会在 XA 事务参与者要提交事务时回滚事务,从而导致试探性完成和数据不一致。
由于存在破坏数据完整性的风险,所以,“仿真两阶段提交”选项仅应在可允许出现试探性情况的应用程序中使用。
无法恢复待定事务
因为非 XA 驱动程序仅对本地数据库事务进行操作,所以,在有关外部事务管理器的数据库中没有事务待定状态的概念。在非 XA 资源上调用XAResource.recover()
时,该方法总是会返回 Xid(事务 ID)的一个空集,即使可能有需要提交或回滚的事务,也是如此。因此,那些在全局事务中使用非 XA 资源的应用程序无法从系统故障中恢复过来,并无法保持数据完整性。
在多服务器配置中使用非 XA 资源时可能产生的性能损失
因为 WebLogic Server 依赖于与特定 JDBC 连接相关联的数据库本地事务来支持全局事务中的非 XA 资源,所以,当某个应用程序通过一个全局事务上下文在多个 WebLogic Server 实例中访问同一 JDBC 数据源时,JTS 驱动程序会始终将 JDBC 操作路由到由该应用程序在事务中建立的第一个连接。例如,如果某个应用程序在一个服务器上启动了某个事务,访问非 XA JDBC 资源,然后对另一个服务器进行远程方法调用(remote method invocation,简称 RMI)并访问某个使用同一底层 JDBC 驱动程序的数据源,则 JTS 驱动程序会识别出该资源具有与其他服务器上的事务相关联的连接,并会设置一个到第一个服务器上的实际连接的 RMI 重定向。对该连接的所有操作都会对建立在第一个服务器上的一个连接执行。此行为可由于与设置这些远程连接和对一个物理连接进行 RMI 调用相关联的开销而导致性能损失。
仅一个非 XA 参与者
将某个非 XA 资源(其“仿真两阶段提交”处于选中状态)注册到 WebLogic Server 事务管理器时,会使用实现 XAResource 接口的类的名称注册该资源。因为其“仿真两阶段提交”处于选中状态的所有非 XA 资源都对 XAResource 接口使用 JTS 驱动程序,所以,会使用同一名称注册所有参与某个全局事务的非 XA 资源(其“仿真两阶段提交”处于选中状态)。如果在某个全局事务中使用多个非 XA 资源,则会导致命名冲突或可能会出现试探性失败。