Skip to content

Commit

Permalink
Introduce an option in narayana-jta for enabling XA recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
zhfeng committed Sep 19, 2022
1 parent bc4a965 commit a9d2345
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.quarkus.datasource.runtime.DataSourceRuntimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig;
import io.quarkus.narayana.jta.runtime.TransactionManagerConfiguration;

/**
* This class is sort of a producer for {@link AgroalDataSource}.
Expand All @@ -72,6 +73,7 @@ public class DataSources {
private final DataSourcesRuntimeConfig dataSourcesRuntimeConfig;
private final DataSourcesJdbcBuildTimeConfig dataSourcesJdbcBuildTimeConfig;
private final DataSourcesJdbcRuntimeConfig dataSourcesJdbcRuntimeConfig;
private final TransactionManagerConfiguration transactionRuntimeConfig;
private final TransactionManager transactionManager;
private final XAResourceRecoveryRegistry xaResourceRecoveryRegistry;
private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
Expand All @@ -83,6 +85,7 @@ public class DataSources {
public DataSources(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig, DataSourcesJdbcBuildTimeConfig dataSourcesJdbcBuildTimeConfig,
DataSourcesJdbcRuntimeConfig dataSourcesJdbcRuntimeConfig,
TransactionManagerConfiguration transactionRuntimeConfig,
TransactionManager transactionManager,
XAResourceRecoveryRegistry xaResourceRecoveryRegistry,
TransactionSynchronizationRegistry transactionSynchronizationRegistry, DataSourceSupport dataSourceSupport,
Expand All @@ -91,6 +94,7 @@ public DataSources(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
this.dataSourcesRuntimeConfig = dataSourcesRuntimeConfig;
this.dataSourcesJdbcBuildTimeConfig = dataSourcesJdbcBuildTimeConfig;
this.dataSourcesJdbcRuntimeConfig = dataSourcesJdbcRuntimeConfig;
this.transactionRuntimeConfig = transactionRuntimeConfig;
this.transactionManager = transactionManager;
this.xaResourceRecoveryRegistry = xaResourceRecoveryRegistry;
this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
Expand Down Expand Up @@ -215,8 +219,10 @@ public AgroalDataSource doCreateDataSource(String dataSourceName) {
.connectionFactoryConfiguration();

boolean mpMetricsPresent = dataSourceSupport.mpMetricsPresent;
applyNewConfiguration(dataSourceConfiguration, poolConfiguration, connectionFactoryConfiguration, driver, jdbcUrl,
dataSourceJdbcBuildTimeConfig, dataSourceRuntimeConfig, dataSourceJdbcRuntimeConfig, mpMetricsPresent);
applyNewConfiguration(dataSourceName, dataSourceConfiguration, poolConfiguration, connectionFactoryConfiguration,
driver, jdbcUrl,
dataSourceJdbcBuildTimeConfig, dataSourceRuntimeConfig, dataSourceJdbcRuntimeConfig, transactionRuntimeConfig,
mpMetricsPresent);

if (dataSourceSupport.disableSslSupport) {
agroalConnectionConfigurer.disableSslSupport(resolvedDbKind, dataSourceConfiguration);
Expand Down Expand Up @@ -255,11 +261,12 @@ public AgroalDataSource doCreateDataSource(String dataSourceName) {
return dataSource;
}

private void applyNewConfiguration(AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
private void applyNewConfiguration(String dataSourceName, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
AgroalConnectionPoolConfigurationSupplier poolConfiguration,
AgroalConnectionFactoryConfigurationSupplier connectionFactoryConfiguration, Class<?> driver, String jdbcUrl,
DataSourceJdbcBuildTimeConfig dataSourceJdbcBuildTimeConfig, DataSourceRuntimeConfig dataSourceRuntimeConfig,
DataSourceJdbcRuntimeConfig dataSourceJdbcRuntimeConfig, boolean mpMetricsPresent) {
DataSourceJdbcRuntimeConfig dataSourceJdbcRuntimeConfig, TransactionManagerConfiguration transactionRuntimeConfig,
boolean mpMetricsPresent) {
connectionFactoryConfiguration.jdbcUrl(jdbcUrl);
connectionFactoryConfiguration.connectionProviderClass(driver);
connectionFactoryConfiguration.trackJdbcResources(dataSourceJdbcRuntimeConfig.detectStatementLeaks);
Expand All @@ -274,8 +281,15 @@ private void applyNewConfiguration(AgroalDataSourceConfigurationSupplier dataSou
TransactionIntegration txIntegration = new NarayanaTransactionIntegration(transactionManager,
transactionSynchronizationRegistry, null, false,
dataSourceJdbcBuildTimeConfig.transactions == io.quarkus.agroal.runtime.TransactionIntegration.XA
? xaResourceRecoveryRegistry
: null);
&& transactionRuntimeConfig.enableXaRecovery
? xaResourceRecoveryRegistry
: null);
if (dataSourceJdbcBuildTimeConfig.transactions == io.quarkus.agroal.runtime.TransactionIntegration.XA
&& !transactionRuntimeConfig.enableXaRecovery) {
log.warnv(
"datasource {0} enables XA but transaction recovery is not enabled. Please use quarkus.transaction-manager.enable-xa-recovery=true otherwise you will have a risk to lose the data consistency when the application crash happens.",
dataSourceName);
}
poolConfiguration.transactionIntegration(txIntegration);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void build(NarayanaJtaRecorder recorder,
BuildProducer<RuntimeInitializedClassBuildItem> runtimeInit,
BuildProducer<FeatureBuildItem> feature,
TransactionManagerConfiguration transactions, ShutdownContextBuildItem shutdownContextBuildItem) {
recorder.handleShutdown(shutdownContextBuildItem);
recorder.handleShutdown(shutdownContextBuildItem, transactions);
feature.produce(new FeatureBuildItem(Feature.NARAYANA_JTA));
additionalBeans.produce(new AdditionalBeanBuildItem(NarayanaJtaProducers.class));
additionalBeans.produce(new AdditionalBeanBuildItem(CDIDelegatingTransactionManager.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ public javax.transaction.UserTransaction userTransaction() {

@Produces
@Singleton
public XAResourceRecoveryRegistry xaResourceRecoveryRegistry() {
public XAResourceRecoveryRegistry xaResourceRecoveryRegistry(TransactionManagerConfiguration config) {
RecoveryManagerService recoveryManagerService = new RecoveryManagerService();
recoveryManagerService.create();
recoveryManagerService.start();
if (config.enableXaRecovery) {
recoveryManagerService.create();
recoveryManagerService.start();
}
return recoveryManagerService;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ public void setConfig(final TransactionManagerConfiguration transactions) {
.setXaResourceOrphanFilterClassNames(transactions.xaResourceOrphanFilters);
}

public void handleShutdown(ShutdownContext context) {
public void handleShutdown(ShutdownContext context, TransactionManagerConfiguration transactions) {
context.addLastShutdownTask(new Runnable() {
@Override
public void run() {
RecoveryManager.manager().terminate(true);
if (transactions.enableXaRecovery) {
RecoveryManager.manager().terminate(true);
}
TransactionReaper.terminate(false);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public final class TransactionManagerConfiguration {
@ConfigItem(defaultValue = "ObjectStore")
public String objectStoreDirectory;

/**
* Enable recovery service to start on startup
*/
@ConfigItem(defaultValue = "false")
public boolean enableXaRecovery;

/**
* The list of recovery modules
*/
Expand Down

0 comments on commit a9d2345

Please sign in to comment.