Introduce lazyTransactionalConnections flag on TransactionAwareDataSourceProxy
Includes revision of JDBC transaction tests. Closes gh-29423
This commit is contained in:
parent
8a82da43c9
commit
47fe61ef79
|
|
@ -76,6 +76,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
|||
*/
|
||||
public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
|
||||
|
||||
private boolean lazyTransactionalConnections = true;
|
||||
|
||||
private boolean reobtainTransactionalConnections = false;
|
||||
|
||||
|
||||
|
|
@ -94,6 +96,18 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
|
|||
super(targetDataSource);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify whether to obtain the transactional target Connection lazily on
|
||||
* actual data access.
|
||||
* <p>The default is "true". Specify "false" to immediately obtain a target
|
||||
* Connection when a transaction-aware Connection handle is retrieved.
|
||||
* @since 6.1.2
|
||||
*/
|
||||
public void setLazyTransactionalConnections(boolean lazyTransactionalConnections) {
|
||||
this.lazyTransactionalConnections = lazyTransactionalConnections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether to reobtain the target Connection for each operation
|
||||
* performed within a transaction.
|
||||
|
|
@ -119,7 +133,12 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
|
|||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return getTransactionAwareConnectionProxy(obtainTargetDataSource());
|
||||
DataSource ds = obtainTargetDataSource();
|
||||
Connection con = getTransactionAwareConnectionProxy(ds);
|
||||
if (!this.lazyTransactionalConnections && shouldObtainFixedConnection(ds)) {
|
||||
((ConnectionProxy) con).getTargetConnection();
|
||||
}
|
||||
return con;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public class DataSourceJtaTransactionTests {
|
|||
|
||||
private Transaction transaction = mock();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
given(dataSource.getConnection()).willReturn(connection);
|
||||
|
|
@ -88,6 +89,7 @@ public class DataSourceJtaTransactionTests {
|
|||
assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testJtaTransactionCommit() throws Exception {
|
||||
doTestJtaTransaction(false);
|
||||
|
|
@ -110,26 +112,23 @@ public class DataSourceJtaTransactionTests {
|
|||
|
||||
JtaTransactionManager ptm = new JtaTransactionManager(userTransaction);
|
||||
TransactionTemplate tt = new TransactionTemplate(ptm);
|
||||
boolean condition3 = !TransactionSynchronizationManager.hasResource(dataSource);
|
||||
assertThat(condition3).as("Hasn't thread connection").isTrue();
|
||||
boolean condition2 = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition2).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dataSource);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(status.isNewTransaction()).isTrue();
|
||||
|
||||
Connection c = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dataSource);
|
||||
Connection con = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dataSource);
|
||||
|
||||
c = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dataSource);
|
||||
con = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dataSource);
|
||||
|
||||
if (rollback) {
|
||||
status.setRollbackOnly();
|
||||
|
|
@ -137,10 +136,8 @@ public class DataSourceJtaTransactionTests {
|
|||
}
|
||||
});
|
||||
|
||||
boolean condition1 = !TransactionSynchronizationManager.hasResource(dataSource);
|
||||
assertThat(condition1).as("Hasn't thread connection").isTrue();
|
||||
boolean condition = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
verify(userTransaction).begin();
|
||||
if (rollback) {
|
||||
verify(userTransaction).rollback();
|
||||
|
|
@ -220,29 +217,26 @@ public class DataSourceJtaTransactionTests {
|
|||
JtaTransactionManager ptm = new JtaTransactionManager(userTransaction, transactionManager);
|
||||
final TransactionTemplate tt = new TransactionTemplate(ptm);
|
||||
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
boolean condition3 = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition3).as("Hasn't thread connection").isTrue();
|
||||
boolean condition2 = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition2).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(status.isNewTransaction()).isTrue();
|
||||
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
try {
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
c.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
con.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
if (!openOuterConnection) {
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
|
|
@ -253,20 +247,19 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(status.isNewTransaction()).isTrue();
|
||||
|
||||
try {
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
c.isReadOnly();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
con.isReadOnly();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
}
|
||||
|
|
@ -282,15 +275,15 @@ public class DataSourceJtaTransactionTests {
|
|||
if (accessAfterResume) {
|
||||
try {
|
||||
if (!openOuterConnection) {
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
}
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
c.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
con.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
}
|
||||
|
|
@ -298,16 +291,14 @@ public class DataSourceJtaTransactionTests {
|
|||
|
||||
else {
|
||||
if (openOuterConnection) {
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
boolean condition1 = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition1).as("Hasn't thread connection").isTrue();
|
||||
boolean condition = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
verify(userTransaction, times(6)).begin();
|
||||
verify(transactionManager, times(5)).resume(transaction);
|
||||
if (rollback) {
|
||||
|
|
@ -480,31 +471,28 @@ public class DataSourceJtaTransactionTests {
|
|||
JtaTransactionManager ptm = new JtaTransactionManager(userTransaction, transactionManager);
|
||||
final TransactionTemplate tt = new TransactionTemplate(ptm);
|
||||
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
boolean condition3 = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition3).as("Hasn't thread connection").isTrue();
|
||||
boolean condition2 = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition2).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
|
||||
assertThatExceptionOfType(TransactionException.class).isThrownBy(() ->
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(status.isNewTransaction()).isTrue();
|
||||
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
try {
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
c.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
con.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
if (!openOuterConnection) {
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
|
|
@ -514,26 +502,25 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(status.isNewTransaction()).isTrue();
|
||||
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
|
||||
c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
if (openOuterConnection) {
|
||||
try {
|
||||
c.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
con.isReadOnly();
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
}
|
||||
|
|
@ -542,10 +529,8 @@ public class DataSourceJtaTransactionTests {
|
|||
}
|
||||
}));
|
||||
|
||||
boolean condition1 = !TransactionSynchronizationManager.hasResource(dsToUse);
|
||||
assertThat(condition1).as("Hasn't thread connection").isTrue();
|
||||
boolean condition = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
|
||||
verify(userTransaction).begin();
|
||||
if (suspendException) {
|
||||
|
|
@ -586,10 +571,8 @@ public class DataSourceJtaTransactionTests {
|
|||
}
|
||||
};
|
||||
TransactionTemplate tt = new TransactionTemplate(ptm);
|
||||
boolean condition2 = !TransactionSynchronizationManager.hasResource(dataSource);
|
||||
assertThat(condition2).as("Hasn't thread connection").isTrue();
|
||||
boolean condition1 = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition1).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
|
||||
given(userTransaction.getStatus()).willReturn(Status.STATUS_ACTIVE);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
|
@ -598,31 +581,28 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
|
||||
boolean condition = !status.isNewTransaction();
|
||||
assertThat(condition).as("Is existing transaction").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(!status.isNewTransaction()).isTrue();
|
||||
|
||||
Connection c = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).as("Has thread connection").isTrue();
|
||||
DataSourceUtils.releaseConnection(c, dataSource);
|
||||
Connection con = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
DataSourceUtils.releaseConnection(con, dataSource);
|
||||
|
||||
c = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).as("Has thread connection").isTrue();
|
||||
con = DataSourceUtils.getConnection(dataSource);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
if (releaseCon) {
|
||||
DataSourceUtils.releaseConnection(c, dataSource);
|
||||
DataSourceUtils.releaseConnection(con, dataSource);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!releaseCon) {
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).as("Still has connection holder").isTrue();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
}
|
||||
else {
|
||||
boolean condition = !TransactionSynchronizationManager.hasResource(dataSource);
|
||||
assertThat(condition).as("Hasn't thread connection").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.hasResource(dataSource)).isTrue();
|
||||
}
|
||||
boolean condition = !TransactionSynchronizationManager.isSynchronizationActive();
|
||||
assertThat(condition).as("JTA synchronizations not active").isTrue();
|
||||
assertThat(!TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
}
|
||||
verify(connection, times(3)).close();
|
||||
}
|
||||
|
|
@ -648,10 +628,10 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
assertThat(c).isSameAs(connection);
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(con).isSameAs(connection);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -660,10 +640,10 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
assertThat(c).isSameAs(connection);
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(con).isSameAs(connection);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -720,10 +700,10 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
assertThat(c).isSameAs(connection1);
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(con).isSameAs(connection1);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -731,10 +711,10 @@ public class DataSourceJtaTransactionTests {
|
|||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
|
||||
Connection c = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
|
||||
assertThat(c).isSameAs(connection2);
|
||||
DataSourceUtils.releaseConnection(c, dsToUse);
|
||||
Connection con = DataSourceUtils.getConnection(dsToUse);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isTrue();
|
||||
assertThat(con).isSameAs(connection2);
|
||||
DataSourceUtils.releaseConnection(con, dsToUse);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -67,20 +67,25 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
|||
* @since 04.07.2003
|
||||
* @see org.springframework.jdbc.support.JdbcTransactionManagerTests
|
||||
*/
|
||||
public class DataSourceTransactionManagerTests {
|
||||
public class DataSourceTransactionManagerTests<T extends DataSourceTransactionManager> {
|
||||
|
||||
private DataSource ds = mock();
|
||||
protected DataSource ds = mock();
|
||||
|
||||
private Connection con = mock();
|
||||
protected Connection con = mock();
|
||||
|
||||
private DataSourceTransactionManager tm = new DataSourceTransactionManager(ds);
|
||||
protected DataSourceTransactionManager tm;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
tm = createTransactionManager(ds);
|
||||
given(ds.getConnection()).willReturn(con);
|
||||
}
|
||||
|
||||
protected DataSourceTransactionManager createTransactionManager(DataSource ds) {
|
||||
return new DataSourceTransactionManager(ds);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void verifyTransactionSynchronizationManagerState() {
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap()).isEmpty();
|
||||
|
|
@ -123,18 +128,15 @@ public class DataSourceTransactionManagerTests {
|
|||
private void doTestTransactionCommitRestoringAutoCommit(
|
||||
boolean autoCommit, boolean lazyConnection, final boolean createStatement) throws Exception {
|
||||
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
|
||||
if (lazyConnection) {
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED);
|
||||
given(con.getWarnings()).willThrow(new SQLException());
|
||||
}
|
||||
|
||||
if (!lazyConnection || createStatement) {
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
}
|
||||
|
||||
final DataSource dsToUse = (lazyConnection ? new LazyConnectionDataSourceProxy(ds) : ds);
|
||||
tm = new DataSourceTransactionManager(dsToUse);
|
||||
tm = createTransactionManager(dsToUse);
|
||||
TransactionTemplate tt = new TransactionTemplate(tm);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isFalse();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse();
|
||||
|
|
@ -213,17 +215,14 @@ public class DataSourceTransactionManagerTests {
|
|||
private void doTestTransactionRollbackRestoringAutoCommit(
|
||||
boolean autoCommit, boolean lazyConnection, final boolean createStatement) throws Exception {
|
||||
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
|
||||
if (lazyConnection) {
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
given(con.getTransactionIsolation()).willReturn(Connection.TRANSACTION_READ_COMMITTED);
|
||||
}
|
||||
|
||||
if (!lazyConnection || createStatement) {
|
||||
given(con.getAutoCommit()).willReturn(autoCommit);
|
||||
}
|
||||
|
||||
final DataSource dsToUse = (lazyConnection ? new LazyConnectionDataSourceProxy(ds) : ds);
|
||||
tm = new DataSourceTransactionManager(dsToUse);
|
||||
tm = createTransactionManager(dsToUse);
|
||||
TransactionTemplate tt = new TransactionTemplate(tm);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).isFalse();
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse();
|
||||
|
|
@ -522,7 +521,7 @@ public class DataSourceTransactionManagerTests {
|
|||
@Test
|
||||
public void testParticipatingTransactionWithRollbackOnlyAndInnerSynch() throws Exception {
|
||||
tm.setTransactionSynchronization(DataSourceTransactionManager.SYNCHRONIZATION_NEVER);
|
||||
DataSourceTransactionManager tm2 = new DataSourceTransactionManager(ds);
|
||||
DataSourceTransactionManager tm2 = createTransactionManager(ds);
|
||||
// tm has no synch enabled (used at outer level), tm2 has synch enabled (inner level)
|
||||
|
||||
assertThat(TransactionSynchronizationManager.hasResource(ds)).isFalse();
|
||||
|
|
@ -613,7 +612,7 @@ public class DataSourceTransactionManagerTests {
|
|||
final TransactionTemplate tt = new TransactionTemplate(tm);
|
||||
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
||||
PlatformTransactionManager tm2 = new DataSourceTransactionManager(ds2);
|
||||
PlatformTransactionManager tm2 = createTransactionManager(ds2);
|
||||
final TransactionTemplate tt2 = new TransactionTemplate(tm2);
|
||||
tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
||||
|
|
@ -662,7 +661,7 @@ public class DataSourceTransactionManagerTests {
|
|||
final TransactionTemplate tt = new TransactionTemplate(tm);
|
||||
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
||||
DataSourceTransactionManager tm2 = new DataSourceTransactionManager(ds2);
|
||||
DataSourceTransactionManager tm2 = createTransactionManager(ds2);
|
||||
tm2.setTransactionSynchronization(DataSourceTransactionManager.SYNCHRONIZATION_NEVER);
|
||||
final TransactionTemplate tt2 = new TransactionTemplate(tm2);
|
||||
tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
|
@ -1023,6 +1022,42 @@ public class DataSourceTransactionManagerTests {
|
|||
verify(con).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionAwareDataSourceProxyWithLazyFalse() throws Exception {
|
||||
given(con.getAutoCommit()).willReturn(true);
|
||||
given(con.getWarnings()).willThrow(new SQLException());
|
||||
|
||||
TransactionTemplate tt = new TransactionTemplate(tm);
|
||||
assertThat(TransactionSynchronizationManager.hasResource(ds)).isFalse();
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
// something transactional
|
||||
assertThat(DataSourceUtils.getConnection(ds)).isEqualTo(con);
|
||||
TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds);
|
||||
dsProxy.setLazyTransactionalConnections(false);
|
||||
try {
|
||||
Connection tCon = dsProxy.getConnection();
|
||||
assertThatExceptionOfType(SQLException.class).isThrownBy(tCon::getWarnings);
|
||||
tCon.clearWarnings();
|
||||
assertThat(((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()).isEqualTo(con);
|
||||
// should be ignored
|
||||
dsProxy.getConnection().close();
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
throw new UncategorizedSQLException("", "", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(TransactionSynchronizationManager.hasResource(ds)).isFalse();
|
||||
InOrder ordered = inOrder(con);
|
||||
ordered.verify(con).setAutoCommit(false);
|
||||
ordered.verify(con).commit();
|
||||
ordered.verify(con).setAutoCommit(true);
|
||||
verify(con).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionAwareDataSourceProxyWithSuspension() throws Exception {
|
||||
given(con.getAutoCommit()).willReturn(true);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue