11/*
2- * Copyright 2002-2024 the original author or authors.
2+ * Copyright 2002-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ public class DataSourceTransactionManagerTests {
7272
7373 protected DataSource ds = mock ();
7474
75- protected Connection con = mock ();
75+ protected ConnectionProxy con = mock ();
7676
7777 protected DataSourceTransactionManager tm ;
7878
@@ -81,6 +81,7 @@ public class DataSourceTransactionManagerTests {
8181 void setup () throws Exception {
8282 tm = createTransactionManager (ds );
8383 given (ds .getConnection ()).willReturn (con );
84+ given (con .getTargetConnection ()).willThrow (new UnsupportedOperationException ());
8485 }
8586
8687 protected DataSourceTransactionManager createTransactionManager (DataSource ds ) {
@@ -1074,9 +1075,9 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
10741075 Connection tCon = dsProxy .getConnection ();
10751076 tCon .getWarnings ();
10761077 tCon .clearWarnings ();
1077- assertThat (((ConnectionProxy ) dsProxy . getConnection () ).getTargetConnection ()).isEqualTo (con );
1078+ assertThat (((ConnectionProxy ) tCon ).getTargetConnection ()).isEqualTo (con );
10781079 // should be ignored
1079- dsProxy . getConnection () .close ();
1080+ tCon .close ();
10801081 }
10811082 catch (SQLException ex ) {
10821083 throw new UncategorizedSQLException ("" , "" , ex );
@@ -1110,9 +1111,9 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
11101111 Connection tCon = dsProxy .getConnection ();
11111112 assertThatExceptionOfType (SQLException .class ).isThrownBy (tCon ::getWarnings );
11121113 tCon .clearWarnings ();
1113- assertThat (((ConnectionProxy ) dsProxy . getConnection () ).getTargetConnection ()).isEqualTo (con );
1114+ assertThat (((ConnectionProxy ) tCon ).getTargetConnection ()).isEqualTo (con );
11141115 // should be ignored
1115- dsProxy . getConnection () .close ();
1116+ tCon .close ();
11161117 }
11171118 catch (SQLException ex ) {
11181119 throw new UncategorizedSQLException ("" , "" , ex );
@@ -1128,6 +1129,42 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
11281129 verify (con ).close ();
11291130 }
11301131
1132+ @ Test
1133+ void testTransactionAwareDataSourceProxyWithEarlyConnection () throws Exception {
1134+ given (ds .getConnection ()).willReturn (mock (Connection .class ), con );
1135+ given (con .getAutoCommit ()).willReturn (true );
1136+ given (con .getWarnings ()).willThrow (new SQLException ());
1137+
1138+ TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy (ds );
1139+ dsProxy .setLazyTransactionalConnections (false );
1140+ Connection tCon = dsProxy .getConnection ();
1141+
1142+ TransactionTemplate tt = new TransactionTemplate (tm );
1143+ assertThat (TransactionSynchronizationManager .hasResource (ds )).isFalse ();
1144+ tt .execute (new TransactionCallbackWithoutResult () {
1145+ @ Override
1146+ protected void doInTransactionWithoutResult (TransactionStatus status ) {
1147+ // something transactional
1148+ assertThat (DataSourceUtils .getConnection (ds )).isEqualTo (con );
1149+ try {
1150+ // should close the early Connection obtained before the transaction
1151+ tCon .close ();
1152+ }
1153+ catch (SQLException ex ) {
1154+ throw new UncategorizedSQLException ("" , "" , ex );
1155+ }
1156+ }
1157+ });
1158+
1159+ assertThat (TransactionSynchronizationManager .hasResource (ds )).isFalse ();
1160+
1161+ InOrder ordered = inOrder (con );
1162+ ordered .verify (con ).setAutoCommit (false );
1163+ ordered .verify (con ).commit ();
1164+ ordered .verify (con ).setAutoCommit (true );
1165+ verify (con ).close ();
1166+ }
1167+
11311168 @ Test
11321169 void testTransactionAwareDataSourceProxyWithSuspension () throws Exception {
11331170 given (con .getAutoCommit ()).willReturn (true );
0 commit comments