mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Consistent handling of early setCatalog/setSchema/setHoldability calls
Closes gh-36527 Closes gh-36528
This commit is contained in:
+57
-22
@@ -21,7 +21,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -300,13 +299,17 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
|
||||
private @Nullable String password;
|
||||
|
||||
private @Nullable Boolean autoCommit;
|
||||
private @Nullable String catalog;
|
||||
|
||||
private @Nullable Integer transactionIsolation;
|
||||
private @Nullable String schema;
|
||||
|
||||
private @Nullable Integer holdability;
|
||||
|
||||
private boolean readOnly = false;
|
||||
|
||||
private int holdability = ResultSet.CLOSE_CURSORS_AT_COMMIT;
|
||||
private @Nullable Integer transactionIsolation;
|
||||
|
||||
private @Nullable Boolean autoCommit;
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
@@ -364,15 +367,41 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
case "toString" -> {
|
||||
return "Lazy Connection proxy for target DataSource [" + getTargetDataSource() + "]";
|
||||
}
|
||||
case "getAutoCommit" -> {
|
||||
if (this.autoCommit != null) {
|
||||
return this.autoCommit;
|
||||
case "getCatalog" -> {
|
||||
if (this.catalog != null) {
|
||||
return this.catalog;
|
||||
}
|
||||
// Else fetch actual Connection and check there,
|
||||
// because we didn't have a default specified.
|
||||
// Else fetch actual Connection and check there.
|
||||
}
|
||||
case "setAutoCommit" -> {
|
||||
this.autoCommit = (Boolean) args[0];
|
||||
case "setCatalog" -> {
|
||||
this.catalog = (String) args[0];
|
||||
return null;
|
||||
}
|
||||
case "getSchema" -> {
|
||||
if (this.schema != null) {
|
||||
return this.schema;
|
||||
}
|
||||
// Else fetch actual Connection and check there.
|
||||
}
|
||||
case "setSchema" -> {
|
||||
this.schema = (String) args[0];
|
||||
return null;
|
||||
}
|
||||
case "getHoldability" -> {
|
||||
if (this.holdability != null) {
|
||||
return this.holdability;
|
||||
}
|
||||
// Else fetch actual Connection and check there.
|
||||
}
|
||||
case "setHoldability" -> {
|
||||
this.holdability = (Integer) args[0];
|
||||
return null;
|
||||
}
|
||||
case "isReadOnly" -> {
|
||||
return (this.readOnly || getTargetDataSource() == readOnlyDataSource);
|
||||
}
|
||||
case "setReadOnly" -> {
|
||||
this.readOnly = (Boolean) args[0];
|
||||
return null;
|
||||
}
|
||||
case "getTransactionIsolation" -> {
|
||||
@@ -386,18 +415,15 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
this.transactionIsolation = (Integer) args[0];
|
||||
return null;
|
||||
}
|
||||
case "isReadOnly" -> {
|
||||
return (this.readOnly || getTargetDataSource() == readOnlyDataSource);
|
||||
case "getAutoCommit" -> {
|
||||
if (this.autoCommit != null) {
|
||||
return this.autoCommit;
|
||||
}
|
||||
// Else fetch actual Connection and check there,
|
||||
// because we didn't have a default specified.
|
||||
}
|
||||
case "setReadOnly" -> {
|
||||
this.readOnly = (Boolean) args[0];
|
||||
return null;
|
||||
}
|
||||
case "getHoldability" -> {
|
||||
return this.holdability;
|
||||
}
|
||||
case "setHoldability" -> {
|
||||
this.holdability = (Integer) args[0];
|
||||
case "setAutoCommit" -> {
|
||||
this.autoCommit = (Boolean) args[0];
|
||||
return null;
|
||||
}
|
||||
case "commit", "rollback" -> {
|
||||
@@ -485,6 +511,15 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
|
||||
// Apply kept transaction settings, if any.
|
||||
try {
|
||||
if (this.catalog != null) {
|
||||
target.setCatalog(this.catalog);
|
||||
}
|
||||
if (this.schema != null) {
|
||||
target.setSchema(this.schema);
|
||||
}
|
||||
if (this.holdability != null) {
|
||||
target.setHoldability(this.holdability);
|
||||
}
|
||||
if (this.readOnly && readOnlyDataSource == null) {
|
||||
DataSourceUtils.setReadOnlyIfPossible(target);
|
||||
}
|
||||
|
||||
+21
-2
@@ -19,6 +19,7 @@ package org.springframework.jdbc.datasource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
import java.sql.Statement;
|
||||
@@ -828,14 +829,32 @@ public class DataSourceTransactionManagerTests {
|
||||
dsProxy.setDefaultAutoCommit(true);
|
||||
dsProxy.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
|
||||
dsProxy.afterPropertiesSet();
|
||||
tm = createTransactionManager(dsProxy);
|
||||
|
||||
try (Connection con = dsProxy.getConnection()) {
|
||||
DelegatingDataSource dsAdapter = new DelegatingDataSource(dsProxy) {
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
Connection con = super.getConnection();
|
||||
con.setCatalog("myCatalog");
|
||||
con.setSchema("mySchema");
|
||||
con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
|
||||
return con;
|
||||
}
|
||||
};
|
||||
|
||||
tm = createTransactionManager(dsAdapter);
|
||||
|
||||
try (Connection con = dsAdapter.getConnection()) {
|
||||
assertThat(con.isReadOnly()).isFalse();
|
||||
assertThat(con.getCatalog()).isEqualTo("myCatalog");
|
||||
assertThat(con.getSchema()).isEqualTo("mySchema");
|
||||
assertThat(con.getHoldability()).isEqualTo(ResultSet.HOLD_CURSORS_OVER_COMMIT);
|
||||
}
|
||||
assertTransactionReadOnly(TransactionDefinition.ISOLATION_SERIALIZABLE, true);
|
||||
|
||||
InOrder ordered = inOrder(con);
|
||||
ordered.verify(con).setCatalog("myCatalog");
|
||||
ordered.verify(con).setSchema("mySchema");
|
||||
ordered.verify(con).setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
|
||||
ordered.verify(con).setReadOnly(true);
|
||||
ordered.verify(con).setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
|
||||
ordered.verify(con).setAutoCommit(false);
|
||||
|
||||
Reference in New Issue
Block a user