1.2.4. 在单个事务中使用多个数据源
默认情况下,数据源上的 XA 支持被禁用。因此,事务中不包含多个数据源。在同一个事务中尝试访问多个非 XA datasources 会导致异常类似如下:
...
Caused by: java.sql.SQLException: Exception in association of connection to existing transaction
at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:130)
...
Caused by: java.sql.SQLException: Failed to enlist. Check if a connection from another datasource is already enlisted to the same transaction
at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:121)
...
允许在同一事务中使用多个 JDBC 数据源:
- 确保您的 JDBC 驱动程序支持 XA。所有支持的 JDBC 驱动程序都执行,但其他 JDBC 驱动程序 可能不。
- 确保您的数据库服务器已配置为启用 XA。
-
通过将
quarkus.datasource[.optional name].jdbc.transactions设置为xa,为每个相关数据源启用 XA 支持。
使用 XA 时,一个数据源的回滚将在事务中注册的每个其他数据源中触发回滚。
目前不支持被动数据源上的 XA 事务。
如果您的事务涉及非数据源资源,请注意它们可能不支持 XA 事务,或者可能需要额外的配置。
如果无法为您的其中一个数据源启用 XA :
- 请注意,仍然通过 Last Resource Commit Optimization (LRCO)支持为所有数据源启用 XA,但仍然通过 Last Resource Commit Optimization (LRCO) 支持。
-
如果您不需要一个数据源的回滚来为其他数据源触发回滚,请考虑将您的代码拆分为多个事务。要做到这一点,请使用
QuarkusTransaction.requiringNew ()/@Transactional (REQUIRES_NEW)或UserTransaction(用于更复杂的用例)。
如果没有其他解决方案正常工作并需要与 Quarkus 3.8 或更早版本兼容,请设置 quarkus.transaction-manager.unsafe-multiple-last-resources,以 允许在多个 非 XA datasources 间启用不安全事务处理。
将此属性设置为 allow 时,事务回滚可能仅适用于最后一个非 XA 数据源,而其他非 XA 数据源则可能已提交其更改。这可能会使系统处于不一致的状态。
或者,允许相同的不安全行为,但在出现时显示警告:
-
将属性设置为
warn-each会记录每个 异常 事务的警告。 -
将 属性设置为
warn-first,会记录 第一个 offending 事务的警告。
我们不推荐使用这个配置属性,并计划在以后删除它。您应该相应地更新您的应用程序。如果您认为您的用例只是保留此选项,请在 Quarkus tracker 中创建一个问题,解释原因。