parent
270317728f
commit
337e645263
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2016 the original author or authors.
|
* Copyright 2012-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -40,7 +40,6 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|
@ -166,22 +165,7 @@ public class JtaAutoConfigurationTests {
|
||||||
AtomikosJtaConfiguration.class);
|
AtomikosJtaConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
|
|
||||||
File epochFile = new File("target/transaction-logs/"
|
File epochFile = new File("target/transaction-logs/tmlog0.log");
|
||||||
+ InetAddress.getLocalHost().getHostAddress() + ".tm0.epoch");
|
|
||||||
assertThat(epochFile.isFile()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void customAtomikosTransactionManagerName() throws BeansException, Exception {
|
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
|
||||||
TestPropertyValues.of(
|
|
||||||
"spring.jta.transactionManagerId:custom",
|
|
||||||
"spring.jta.logDir:target/transaction-logs").applyTo(this.context);
|
|
||||||
this.context.register(JtaPropertiesConfiguration.class,
|
|
||||||
AtomikosJtaConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
|
|
||||||
File epochFile = new File("target/transaction-logs/custom0.epoch");
|
|
||||||
assertThat(epochFile.isFile()).isTrue();
|
assertThat(epochFile.isFile()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
<artemis.version>1.5.5</artemis.version>
|
<artemis.version>1.5.5</artemis.version>
|
||||||
<aspectj.version>1.8.10</aspectj.version>
|
<aspectj.version>1.8.10</aspectj.version>
|
||||||
<assertj.version>3.8.0</assertj.version>
|
<assertj.version>3.8.0</assertj.version>
|
||||||
<atomikos.version>3.9.3</atomikos.version>
|
<atomikos.version>4.0.4</atomikos.version>
|
||||||
<bitronix.version>2.1.4</bitronix.version>
|
<bitronix.version>2.1.4</bitronix.version>
|
||||||
<byte-buddy.version>1.6.14</byte-buddy.version>
|
<byte-buddy.version>1.6.14</byte-buddy.version>
|
||||||
<caffeine.version>2.5.1</caffeine.version>
|
<caffeine.version>2.5.1</caffeine.version>
|
||||||
|
|
|
||||||
|
|
@ -738,6 +738,7 @@ content into your application; rather pick only the properties that you need.
|
||||||
spring.jta.atomikos.datasource.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit.
|
spring.jta.atomikos.datasource.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit.
|
||||||
spring.jta.atomikos.datasource.test-query= # SQL query or statement used to validate a connection before returning it.
|
spring.jta.atomikos.datasource.test-query= # SQL query or statement used to validate a connection before returning it.
|
||||||
spring.jta.atomikos.datasource.unique-resource-name=dataSource # The unique name used to identify the resource during recovery.
|
spring.jta.atomikos.datasource.unique-resource-name=dataSource # The unique name used to identify the resource during recovery.
|
||||||
|
spring.jta.atomikos.properties.allow-sub-transactions=true # Specify if sub-transactions are allowed.
|
||||||
spring.jta.atomikos.properties.checkpoint-interval=500 # Interval between checkpoints.
|
spring.jta.atomikos.properties.checkpoint-interval=500 # Interval between checkpoints.
|
||||||
spring.jta.atomikos.properties.console-file-count=1 # Number of debug logs files that can be created.
|
spring.jta.atomikos.properties.console-file-count=1 # Number of debug logs files that can be created.
|
||||||
spring.jta.atomikos.properties.console-file-limit=-1 # How many bytes can be stored at most in debug logs files.
|
spring.jta.atomikos.properties.console-file-limit=-1 # How many bytes can be stored at most in debug logs files.
|
||||||
|
|
@ -751,6 +752,10 @@ content into your application; rather pick only the properties that you need.
|
||||||
spring.jta.atomikos.properties.max-actives=50 # Maximum number of active transactions.
|
spring.jta.atomikos.properties.max-actives=50 # Maximum number of active transactions.
|
||||||
spring.jta.atomikos.properties.max-timeout=300000 # Maximum timeout (in milliseconds) that can be allowed for transactions.
|
spring.jta.atomikos.properties.max-timeout=300000 # Maximum timeout (in milliseconds) that can be allowed for transactions.
|
||||||
spring.jta.atomikos.properties.output-dir= # Directory in which to store the debug log files.
|
spring.jta.atomikos.properties.output-dir= # Directory in which to store the debug log files.
|
||||||
|
spring.jta.atomikos.properties.recovery.delay=10000 # Delay between two recovery scans.
|
||||||
|
spring.jta.atomikos.properties.recovery.forget-orphaned-log-entries-delay=86400000 # Delay after which recovery can cleanup pending ('orphaned') log entries.
|
||||||
|
spring.jta.atomikos.properties.recovery.max-retries=5 # Number of retries attempts to commit the transaction before throwing an exception.
|
||||||
|
spring.jta.atomikos.properties.recovery.retry-interval=10000 # Delay between retry attempts.
|
||||||
spring.jta.atomikos.properties.serial-jta-transactions=true # Specify if sub-transactions should be joined when possible.
|
spring.jta.atomikos.properties.serial-jta-transactions=true # Specify if sub-transactions should be joined when possible.
|
||||||
spring.jta.atomikos.properties.service= # Transaction manager implementation that should be started.
|
spring.jta.atomikos.properties.service= # Transaction manager implementation that should be started.
|
||||||
spring.jta.atomikos.properties.threaded-two-phase-commit=false # Use different (and concurrent) threads for two-phase commit on the participating resources.
|
spring.jta.atomikos.properties.threaded-two-phase-commit=false # Use different (and concurrent) threads for two-phase commit on the participating resources.
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,11 @@ public class AtomikosProperties {
|
||||||
*/
|
*/
|
||||||
private boolean serialJtaTransactions = true;
|
private boolean serialJtaTransactions = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify if sub-transactions are allowed.
|
||||||
|
*/
|
||||||
|
private boolean allowSubTransactions = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify if a VM shutdown should trigger forced shutdown of the transaction core.
|
* Specify if a VM shutdown should trigger forced shutdown of the transaction core.
|
||||||
*/
|
*/
|
||||||
|
|
@ -126,6 +131,8 @@ public class AtomikosProperties {
|
||||||
*/
|
*/
|
||||||
private boolean threadedTwoPhaseCommit;
|
private boolean threadedTwoPhaseCommit;
|
||||||
|
|
||||||
|
private final Recovery recovery = new Recovery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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,
|
||||||
|
|
@ -235,6 +242,14 @@ public class AtomikosProperties {
|
||||||
return this.serialJtaTransactions;
|
return this.serialJtaTransactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAllowSubTransactions(boolean allowSubTransactions) {
|
||||||
|
this.allowSubTransactions = allowSubTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowSubTransactions() {
|
||||||
|
return this.allowSubTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether VM shutdown should trigger forced shutdown of the transaction
|
* Specifies whether VM shutdown should trigger forced shutdown of the transaction
|
||||||
* core. Defaults to false.
|
* core. Defaults to false.
|
||||||
|
|
@ -370,6 +385,10 @@ public class AtomikosProperties {
|
||||||
return this.threadedTwoPhaseCommit;
|
return this.threadedTwoPhaseCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Recovery getRecovery() {
|
||||||
|
return this.recovery;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
|
@ -384,6 +403,7 @@ public class AtomikosProperties {
|
||||||
set(properties, "enable_logging", isEnableLogging());
|
set(properties, "enable_logging", isEnableLogging());
|
||||||
set(properties, "tm_unique_name", getTransactionManagerUniqueName());
|
set(properties, "tm_unique_name", getTransactionManagerUniqueName());
|
||||||
set(properties, "serial_jta_transactions", isSerialJtaTransactions());
|
set(properties, "serial_jta_transactions", isSerialJtaTransactions());
|
||||||
|
set(properties, "allow_subtransactions", isAllowSubTransactions());
|
||||||
set(properties, "force_shutdown_on_vm_exit", isForceShutdownOnVmExit());
|
set(properties, "force_shutdown_on_vm_exit", isForceShutdownOnVmExit());
|
||||||
set(properties, "log_base_name", getLogBaseName());
|
set(properties, "log_base_name", getLogBaseName());
|
||||||
set(properties, "log_base_dir", getLogBaseDir());
|
set(properties, "log_base_dir", getLogBaseDir());
|
||||||
|
|
@ -394,6 +414,12 @@ public class AtomikosProperties {
|
||||||
set(properties, "console_file_count", getConsoleFileCount());
|
set(properties, "console_file_count", getConsoleFileCount());
|
||||||
set(properties, "console_file_limit", getConsoleFileLimit());
|
set(properties, "console_file_limit", getConsoleFileLimit());
|
||||||
set(properties, "threaded_2pc", isThreadedTwoPhaseCommit());
|
set(properties, "threaded_2pc", isThreadedTwoPhaseCommit());
|
||||||
|
Recovery recovery = getRecovery();
|
||||||
|
set(properties, "forget_orphaned_log_entries_delay",
|
||||||
|
recovery.getForgetOrphanedLogEntriesDelay());
|
||||||
|
set(properties, "recovery_delay", recovery.getDelay());
|
||||||
|
set(properties, "oltp_max_retries", recovery.getMaxRetries());
|
||||||
|
set(properties, "oltp_retry_interval", recovery.getRetryInterval());
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,4 +430,64 @@ public class AtomikosProperties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recovery specific settings.
|
||||||
|
*/
|
||||||
|
public static class Recovery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay after which recovery can cleanup pending ('orphaned') log entries.
|
||||||
|
*/
|
||||||
|
private long forgetOrphanedLogEntriesDelay = 86400000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay between two recovery scans.
|
||||||
|
*/
|
||||||
|
private long delay = 10000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of retries attempts to commit the transaction before throwing an
|
||||||
|
* exception.
|
||||||
|
*/
|
||||||
|
private int maxRetries = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay between retry attempts.
|
||||||
|
*/
|
||||||
|
private long retryInterval = 10000;
|
||||||
|
|
||||||
|
public long getForgetOrphanedLogEntriesDelay() {
|
||||||
|
return this.forgetOrphanedLogEntriesDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForgetOrphanedLogEntriesDelay(long forgetOrphanedLogEntriesDelay) {
|
||||||
|
this.forgetOrphanedLogEntriesDelay = forgetOrphanedLogEntriesDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDelay() {
|
||||||
|
return this.delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelay(long delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxRetries() {
|
||||||
|
return this.maxRetries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxRetries(int maxRetries) {
|
||||||
|
this.maxRetries = maxRetries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRetryInterval() {
|
||||||
|
return this.retryInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRetryInterval(long retryInterval) {
|
||||||
|
this.retryInterval = retryInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,13 @@
|
||||||
|
|
||||||
package org.springframework.boot.jta.atomikos;
|
package org.springframework.boot.jta.atomikos;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.assertj.core.data.MapEntry;
|
import org.assertj.core.data.MapEntry;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.entry;
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
|
@ -47,6 +46,7 @@ public class AtomikosPropertiesTests {
|
||||||
this.properties.setEnableLogging(true);
|
this.properties.setEnableLogging(true);
|
||||||
this.properties.setTransactionManagerUniqueName("uniqueName");
|
this.properties.setTransactionManagerUniqueName("uniqueName");
|
||||||
this.properties.setSerialJtaTransactions(true);
|
this.properties.setSerialJtaTransactions(true);
|
||||||
|
this.properties.setAllowSubTransactions(false);
|
||||||
this.properties.setForceShutdownOnVmExit(true);
|
this.properties.setForceShutdownOnVmExit(true);
|
||||||
this.properties.setLogBaseName("logBaseName");
|
this.properties.setLogBaseName("logBaseName");
|
||||||
this.properties.setLogBaseDir("logBaseDir");
|
this.properties.setLogBaseDir("logBaseDir");
|
||||||
|
|
@ -57,8 +57,12 @@ public class AtomikosPropertiesTests {
|
||||||
this.properties.setConsoleFileCount(5);
|
this.properties.setConsoleFileCount(5);
|
||||||
this.properties.setConsoleFileLimit(6);
|
this.properties.setConsoleFileLimit(6);
|
||||||
this.properties.setThreadedTwoPhaseCommit(true);
|
this.properties.setThreadedTwoPhaseCommit(true);
|
||||||
|
this.properties.getRecovery().setForgetOrphanedLogEntriesDelay(2000);
|
||||||
|
this.properties.getRecovery().setDelay(3000);
|
||||||
|
this.properties.getRecovery().setMaxRetries(10);
|
||||||
|
this.properties.getRecovery().setRetryInterval(4000);
|
||||||
|
|
||||||
assertThat(this.properties.asProperties().size()).isEqualTo(17);
|
assertThat(this.properties.asProperties().size()).isEqualTo(22);
|
||||||
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");
|
||||||
|
|
@ -66,6 +70,7 @@ public class AtomikosPropertiesTests {
|
||||||
assertProperty("com.atomikos.icatch.enable_logging", "true");
|
assertProperty("com.atomikos.icatch.enable_logging", "true");
|
||||||
assertProperty("com.atomikos.icatch.tm_unique_name", "uniqueName");
|
assertProperty("com.atomikos.icatch.tm_unique_name", "uniqueName");
|
||||||
assertProperty("com.atomikos.icatch.serial_jta_transactions", "true");
|
assertProperty("com.atomikos.icatch.serial_jta_transactions", "true");
|
||||||
|
assertProperty("com.atomikos.icatch.allow_subtransactions", "false");
|
||||||
assertProperty("com.atomikos.icatch.force_shutdown_on_vm_exit", "true");
|
assertProperty("com.atomikos.icatch.force_shutdown_on_vm_exit", "true");
|
||||||
assertProperty("com.atomikos.icatch.log_base_name", "logBaseName");
|
assertProperty("com.atomikos.icatch.log_base_name", "logBaseName");
|
||||||
assertProperty("com.atomikos.icatch.log_base_dir", "logBaseDir");
|
assertProperty("com.atomikos.icatch.log_base_dir", "logBaseDir");
|
||||||
|
|
@ -76,6 +81,10 @@ public class AtomikosPropertiesTests {
|
||||||
assertProperty("com.atomikos.icatch.console_file_count", "5");
|
assertProperty("com.atomikos.icatch.console_file_count", "5");
|
||||||
assertProperty("com.atomikos.icatch.console_file_limit", "6");
|
assertProperty("com.atomikos.icatch.console_file_limit", "6");
|
||||||
assertProperty("com.atomikos.icatch.threaded_2pc", "true");
|
assertProperty("com.atomikos.icatch.threaded_2pc", "true");
|
||||||
|
assertProperty("com.atomikos.icatch.forget_orphaned_log_entries_delay", "2000");
|
||||||
|
assertProperty("com.atomikos.icatch.recovery_delay", "3000");
|
||||||
|
assertProperty("com.atomikos.icatch.oltp_max_retries", "10");
|
||||||
|
assertProperty("com.atomikos.icatch.oltp_retry_interval", "4000");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -87,16 +96,22 @@ public class AtomikosPropertiesTests {
|
||||||
"com.atomikos.icatch.default_jta_timeout",
|
"com.atomikos.icatch.default_jta_timeout",
|
||||||
"com.atomikos.icatch.max_actives", "com.atomikos.icatch.enable_logging",
|
"com.atomikos.icatch.max_actives", "com.atomikos.icatch.enable_logging",
|
||||||
"com.atomikos.icatch.serial_jta_transactions",
|
"com.atomikos.icatch.serial_jta_transactions",
|
||||||
|
"com.atomikos.icatch.allow_subtransactions",
|
||||||
"com.atomikos.icatch.force_shutdown_on_vm_exit",
|
"com.atomikos.icatch.force_shutdown_on_vm_exit",
|
||||||
"com.atomikos.icatch.log_base_name",
|
"com.atomikos.icatch.log_base_name",
|
||||||
"com.atomikos.icatch.checkpoint_interval",
|
"com.atomikos.icatch.checkpoint_interval",
|
||||||
"com.atomikos.icatch.threaded_2pc"));
|
"com.atomikos.icatch.threaded_2pc",
|
||||||
|
"com.atomikos.icatch.forget_orphaned_log_entries_delay",
|
||||||
|
"com.atomikos.icatch.oltp_max_retries",
|
||||||
|
"com.atomikos.icatch.oltp_retry_interval"));
|
||||||
assertThat(properties).contains(
|
assertThat(properties).contains(
|
||||||
|
entry("com.atomikos.icatch.recovery_delay", defaultSettings.get(
|
||||||
|
"com.atomikos.icatch.default_jta_timeout")),
|
||||||
entry("com.atomikos.icatch.console_log_level", "WARN"),
|
entry("com.atomikos.icatch.console_log_level", "WARN"),
|
||||||
entry("com.atomikos.icatch.console_file_name", "tm.out"),
|
entry("com.atomikos.icatch.console_file_name", "tm.out"),
|
||||||
entry("com.atomikos.icatch.console_file_count", "1"),
|
entry("com.atomikos.icatch.console_file_count", "1"),
|
||||||
entry("com.atomikos.icatch.console_file_limit", "-1"));
|
entry("com.atomikos.icatch.console_file_limit", "-1"));
|
||||||
assertThat(properties).hasSize(13);
|
assertThat(properties).hasSize(18);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) {
|
private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) {
|
||||||
|
|
@ -110,12 +125,9 @@ public class AtomikosPropertiesTests {
|
||||||
|
|
||||||
private Properties loadDefaultSettings() {
|
private Properties loadDefaultSettings() {
|
||||||
try {
|
try {
|
||||||
Class<?> target = ClassUtils.forName(
|
|
||||||
"com.atomikos.icatch.standalone.UserTransactionServiceImp",
|
return PropertiesLoaderUtils.loadProperties(
|
||||||
getClass().getClassLoader());
|
new ClassPathResource("transactions-defaults.properties"));
|
||||||
Method m = target.getMethod("getDefaultProperties");
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (Properties) ReflectionUtils.invokeMethod(m, null);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Failed to get default from Atomikos", ex);
|
throw new IllegalStateException("Failed to get default from Atomikos", ex);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue