Commit 46d94aba authored by nklmish's avatar nklmish Committed by Stephane Nicoll

Allow graceful shutdown of Atomikos

See gh-11237
parent 2da6675c
...@@ -53,6 +53,7 @@ import org.springframework.util.StringUtils; ...@@ -53,6 +53,7 @@ import org.springframework.util.StringUtils;
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Kazuki Shimizu * @author Kazuki Shimizu
* @author Nakul Mishra
* @since 1.2.0 * @since 1.2.0
*/ */
@Configuration @Configuration
...@@ -72,7 +73,7 @@ class AtomikosJtaConfiguration { ...@@ -72,7 +73,7 @@ class AtomikosJtaConfiguration {
.getIfAvailable(); .getIfAvailable();
} }
@Bean(initMethod = "init", destroyMethod = "shutdownForce") @Bean(initMethod = "init", destroyMethod = "shutdownWait")
@ConditionalOnMissingBean(UserTransactionService.class) @ConditionalOnMissingBean(UserTransactionService.class)
public UserTransactionServiceImp userTransactionService( public UserTransactionServiceImp userTransactionService(
AtomikosProperties atomikosProperties) { AtomikosProperties atomikosProperties) {
......
...@@ -29,6 +29,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; ...@@ -29,6 +29,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Nakul Mishra
* @since 1.2.0 * @since 1.2.0
* @see #asProperties() * @see #asProperties()
*/ */
...@@ -107,6 +108,11 @@ public class AtomikosProperties { ...@@ -107,6 +108,11 @@ public class AtomikosProperties {
private final Recovery recovery = new Recovery(); private final Recovery recovery = new Recovery();
/**
* How long should normal shutdown (no-force) wait for transactions to complete.
*/
private long defaultMaxWaitTimeOnShutdown = Long.MAX_VALUE;
/** /**
* Specifies the transaction manager implementation that should be started. There is * Specifies the transaction manager implementation that should be started. There is
* no default value and this must be set. Generally, * no default value and this must be set. Generally,
...@@ -300,6 +306,19 @@ public class AtomikosProperties { ...@@ -300,6 +306,19 @@ public class AtomikosProperties {
return this.recovery; return this.recovery;
} }
/**
* Specifies how long should a normal shutdown (no-force) wait for transactions to complete.
* Defaults to {@literal Long.MAX_VALUE}.
* @param defaultMaxWaitTimeOnShutdown the default max wait time on shutdown
*/
public void setDefaultMaxWaitTimeOnShutdown(long defaultMaxWaitTimeOnShutdown) {
this.defaultMaxWaitTimeOnShutdown = defaultMaxWaitTimeOnShutdown;
}
public long getDefaultMaxWaitTimeOnShutdown() {
return this.defaultMaxWaitTimeOnShutdown;
}
/** /**
* Returns the properties as a {@link Properties} object that can be used with * Returns the properties as a {@link Properties} object that can be used with
* Atomikos. * Atomikos.
...@@ -326,6 +345,7 @@ public class AtomikosProperties { ...@@ -326,6 +345,7 @@ public class AtomikosProperties {
set(properties, "recovery_delay", recovery.getDelay()); set(properties, "recovery_delay", recovery.getDelay());
set(properties, "oltp_max_retries", recovery.getMaxRetries()); set(properties, "oltp_max_retries", recovery.getMaxRetries());
set(properties, "oltp_retry_interval", recovery.getRetryInterval()); set(properties, "oltp_retry_interval", recovery.getRetryInterval());
set(properties, "default_max_wait_time_on_shutdown", getDefaultMaxWaitTimeOnShutdown());
return properties; return properties;
} }
......
...@@ -33,6 +33,7 @@ import static org.assertj.core.api.Assertions.entry; ...@@ -33,6 +33,7 @@ import static org.assertj.core.api.Assertions.entry;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Nakul Mishra
*/ */
public class AtomikosPropertiesTests { public class AtomikosPropertiesTests {
...@@ -58,7 +59,8 @@ public class AtomikosPropertiesTests { ...@@ -58,7 +59,8 @@ public class AtomikosPropertiesTests {
this.properties.getRecovery().setDelay(Duration.ofMillis(3000)); this.properties.getRecovery().setDelay(Duration.ofMillis(3000));
this.properties.getRecovery().setMaxRetries(10); this.properties.getRecovery().setMaxRetries(10);
this.properties.getRecovery().setRetryInterval(Duration.ofMillis(4000)); this.properties.getRecovery().setRetryInterval(Duration.ofMillis(4000));
assertThat(this.properties.asProperties().size()).isEqualTo(17); this.properties.setDefaultMaxWaitTimeOnShutdown(20);
assertThat(this.properties.asProperties().size()).isEqualTo(18);
assertProperty("com.atomikos.icatch.service", "service"); assertProperty("com.atomikos.icatch.service", "service");
assertProperty("com.atomikos.icatch.max_timeout", "1"); assertProperty("com.atomikos.icatch.max_timeout", "1");
assertProperty("com.atomikos.icatch.default_jta_timeout", "2"); assertProperty("com.atomikos.icatch.default_jta_timeout", "2");
...@@ -76,6 +78,7 @@ public class AtomikosPropertiesTests { ...@@ -76,6 +78,7 @@ public class AtomikosPropertiesTests {
assertProperty("com.atomikos.icatch.recovery_delay", "3000"); assertProperty("com.atomikos.icatch.recovery_delay", "3000");
assertProperty("com.atomikos.icatch.oltp_max_retries", "10"); assertProperty("com.atomikos.icatch.oltp_max_retries", "10");
assertProperty("com.atomikos.icatch.oltp_retry_interval", "4000"); assertProperty("com.atomikos.icatch.oltp_retry_interval", "4000");
assertProperty("com.atomikos.icatch.default_max_wait_time_on_shutdown", "20");
} }
@Test @Test
...@@ -94,10 +97,11 @@ public class AtomikosPropertiesTests { ...@@ -94,10 +97,11 @@ public class AtomikosPropertiesTests {
"com.atomikos.icatch.threaded_2pc", "com.atomikos.icatch.threaded_2pc",
"com.atomikos.icatch.forget_orphaned_log_entries_delay", "com.atomikos.icatch.forget_orphaned_log_entries_delay",
"com.atomikos.icatch.oltp_max_retries", "com.atomikos.icatch.oltp_max_retries",
"com.atomikos.icatch.oltp_retry_interval")); "com.atomikos.icatch.oltp_retry_interval",
"com.atomikos.icatch.default_max_wait_time_on_shutdown"));
assertThat(properties).contains(entry("com.atomikos.icatch.recovery_delay", assertThat(properties).contains(entry("com.atomikos.icatch.recovery_delay",
defaultSettings.get("com.atomikos.icatch.default_jta_timeout"))); defaultSettings.get("com.atomikos.icatch.default_jta_timeout")));
assertThat(properties).hasSize(14); assertThat(properties).hasSize(15);
} }
private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) { private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment