Skip to content

Commit 1d7fc55

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

File tree

4 files changed

+99
-0
lines changed

4 files changed

+99
-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.enable-recovery=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.enable-recovery=false
15+
quarkus.datasource.xaNoRecover.jdbc.transactions=xa

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

+14
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ public interface DataSourceJdbcRuntimeConfig {
133133
@WithDefault("true")
134134
boolean poolingEnabled();
135135

136+
/**
137+
* Whether to enable recover for this datasource.
138+
* <p>
139+
* Normally a transaction manager will call xa_recover () on an XA connection during recovery to obtain
140+
* a list of transaction branches that are currently in a prepared or heuristically completed state.
141+
* However, it can happen that multiple XA connections connect to the same database which would all
142+
* return the same set of branches and for reasons of improved performance only one should be used
143+
* for recover() calls. The default value for this configuration property is true because when there
144+
* is only one connection it is vital for data consistency that the connection is able to report its
145+
* list of prepared or heuristically completed branches.
146+
*/
147+
@WithDefault("true")
148+
boolean enableRecovery();
149+
136150
/**
137151
* Require an active transaction when acquiring a connection. Recommended for production.
138152
* 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.enableRecovery());
351352
}
352353

353354
}

0 commit comments

Comments
 (0)