Avoid internal lifecycle synchronization in favor of lifecycle lock

Closes gh-32284
This commit is contained in:
Juergen Hoeller
2024-02-16 12:42:39 +01:00
parent 34372ee32b
commit 7ee8e66c7f
2 changed files with 95 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.lang.Nullable;
@@ -73,8 +75,8 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
@Nullable
private Connection connection;
/** Synchronization monitor for the shared Connection. */
private final Object connectionMonitor = new Object();
/** Lifecycle lock for the shared Connection. */
private final Lock connectionLock = new ReentrantLock();
/**
@@ -181,7 +183,8 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
@Override
public Connection getConnection() throws SQLException {
synchronized (this.connectionMonitor) {
this.connectionLock.lock();
try {
if (this.connection == null) {
// No underlying Connection -> lazy init via DriverManager.
initConnection();
@@ -193,6 +196,9 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
}
return this.connection;
}
finally {
this.connectionLock.unlock();
}
}
/**
@@ -216,9 +222,13 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
*/
@Override
public boolean shouldClose(Connection con) {
synchronized (this.connectionMonitor) {
this.connectionLock.lock();
try {
return (con != this.connection && con != this.target);
}
finally {
this.connectionLock.unlock();
}
}
/**
@@ -241,11 +251,15 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
*/
@Override
public void destroy() {
synchronized (this.connectionMonitor) {
this.connectionLock.lock();
try {
if (this.target != null) {
closeConnection(this.target);
}
}
finally {
this.connectionLock.unlock();
}
}
@@ -256,7 +270,8 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
if (getUrl() == null) {
throw new IllegalStateException("'url' property is required for lazily initializing a Connection");
}
synchronized (this.connectionMonitor) {
this.connectionLock.lock();
try {
if (this.target != null) {
closeConnection(this.target);
}
@@ -267,19 +282,26 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
}
this.connection = (isSuppressClose() ? getCloseSuppressingConnectionProxy(this.target) : this.target);
}
finally {
this.connectionLock.unlock();
}
}
/**
* Reset the underlying shared Connection, to be reinitialized on next access.
*/
public void resetConnection() {
synchronized (this.connectionMonitor) {
this.connectionLock.lock();
try {
if (this.target != null) {
closeConnection(this.target);
}
this.target = null;
this.connection = null;
}
finally {
this.connectionLock.unlock();
}
}
/**