Skip to content

Commit c3ccf56

Browse files
committed
47117 config property to disable datasource recovery
1 parent 7a4e660 commit c3ccf56

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package io.quarkus.agroal.test;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.sql.SQLException;
8+
9+
import jakarta.enterprise.context.control.ActivateRequestContext;
10+
import jakarta.inject.Inject;
11+
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.RegisterExtension;
14+
15+
import io.agroal.api.AgroalDataSource;
16+
import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
17+
import io.agroal.narayana.NarayanaTransactionIntegration;
18+
import io.quarkus.agroal.DataSource;
19+
import io.quarkus.narayana.jta.QuarkusTransaction;
20+
import io.quarkus.test.QuarkusUnitTest;
21+
22+
public class XaDataSourceConfigTest {
23+
24+
//tag::injection[]
25+
@Inject
26+
@DataSource("xa")
27+
AgroalDataSource xaRecoverDS;
28+
29+
@Inject
30+
@DataSource("xaNoRecover")
31+
AgroalDataSource xaNoRecoverDS;
32+
//end::injection[]
33+
34+
@RegisterExtension
35+
static final QuarkusUnitTest config = new QuarkusUnitTest()
36+
.withConfigurationResource("application-recovery-datasources.properties");
37+
38+
@Test
39+
@ActivateRequestContext
40+
public void testEnlistDatasourcesWithRecovery() throws SQLException {
41+
AgroalConnectionPoolConfiguration xaRecoverConfig = xaRecoverDS.getConfiguration().connectionPoolConfiguration();
42+
AgroalConnectionPoolConfiguration xaNoRecoverConfig = xaNoRecoverDS.getConfiguration().connectionPoolConfiguration();
43+
44+
assertTrue(xaRecoverConfig.recoveryEnable(), "xaRecoverDS datasource should have recover enabled");
45+
assertFalse(xaNoRecoverConfig.recoveryEnable(), "xaNoRecoverDS datasource should not have recover enabled");
46+
47+
assertInstanceOf(NarayanaTransactionIntegration.class, xaRecoverConfig.transactionIntegration(),
48+
"Agroal transaction integration should use Narayana for xaRecoverDS");
49+
assertInstanceOf(NarayanaTransactionIntegration.class, xaNoRecoverConfig.transactionIntegration(),
50+
"Agroal transaction integration should use Narayana for xaNoRecoverDS");
51+
52+
// run a transaction and use the two datasources, ensuring that it commits ok
53+
QuarkusTransaction.begin();
54+
55+
// Remark: the two datasources will have been registered with the transaction recovery system because the config
56+
// includes quarkus.transaction-manager.enable-recovery=true
57+
// see QuarkusRecoveryService for details of how the recovery service manages connections to datasources
58+
try (var conn = xaRecoverDS.getConnection()) {
59+
assertFalse(conn.getAutoCommit(), "XA connection should not have the auto commit flag set");
60+
try (var conn2 = xaNoRecoverDS.getConnection()) {
61+
assertFalse(conn2.getAutoCommit(), "XA connection should not have the auto commit flag set");
62+
}
63+
}
64+
65+
assertTrue(QuarkusTransaction.isActive(), "transaction should still have been active");
66+
67+
QuarkusTransaction.commit();
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
quarkus.transaction-manager.enable-recovery=true
2+
3+
quarkus.datasource.xa.db-kind=h2
4+
quarkus.datasource.xa.username=username1
5+
quarkus.datasource.xa.jdbc.driver=org.h2.jdbcx.JdbcDataSource
6+
quarkus.datasource.xa.jdbc.url=jdbc:h2:tcp://localhost/mem:recover
7+
quarkus.datasource.xa.jdbc.recovery-enable=true
8+
quarkus.datasource.xa.jdbc.transactions=xa
9+
10+
quarkus.datasource.xaNoRecover.db-kind=h2
11+
quarkus.datasource.xaNoRecover.username=username1
12+
quarkus.datasource.xaNoRecover.jdbc.driver=org.h2.jdbcx.JdbcDataSource
13+
quarkus.datasource.xaNoRecover.jdbc.url=jdbc:h2:tcp://localhost/mem:recover
14+
quarkus.datasource.xaNoRecover.jdbc.recovery-enable=false
15+
quarkus.datasource.xaNoRecover.jdbc.transactions=xa

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcRuntimeConfig.java

+20
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ public interface DataSourceJdbcRuntimeConfig {
9797
@WithDefault("false")
9898
boolean flushOnClose();
9999

100+
/**
101+
* Allows connections to be registered with the transaction recovery system. It's enabled by default.
102+
*/
103+
@WithDefault("true")
104+
boolean recoveryEnable();
105+
100106
/**
101107
* When enabled, Agroal will be able to produce a warning when a connection is returned
102108
* to the pool without the application having closed all open statements.
@@ -133,6 +139,20 @@ public interface DataSourceJdbcRuntimeConfig {
133139
@WithDefault("true")
134140
boolean poolingEnabled();
135141

142+
/**
143+
* Whether to enable recover for this datasource.
144+
* <p>
145+
* Normally a transaction manager will call xa_recover () on an XA connection during recovery to obtain
146+
* a list of transaction branches that are currently in a prepared or heuristically completed state.
147+
* However, it can happen that multiple XA connections connect to the same database which would all
148+
* return the same set of branches and for reasons of improved performance only one should be used
149+
* for recover() calls. The default value for this configuration property is true because when there
150+
* is only one connection it is vital for data consistency that the connection is able to report its
151+
* list of prepared or heuristically completed branches.
152+
*/
153+
@WithDefault("true")
154+
boolean recoveryEnabled();
155+
136156
/**
137157
* Require an active transaction when acquiring a connection. Recommended for production.
138158
* WARNING: Some extensions acquire connections without holding a transaction for things like schema updates and schema

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSources.java

+1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ public boolean isValid(Connection connection) {
348348
}
349349
poolConfiguration.enhancedLeakReport(dataSourceJdbcRuntimeConfig.extendedLeakReport());
350350
poolConfiguration.flushOnClose(dataSourceJdbcRuntimeConfig.flushOnClose());
351+
poolConfiguration.recoveryEnable(dataSourceJdbcRuntimeConfig.recoveryEnable());
351352
}
352353

353354
}

0 commit comments

Comments
 (0)