mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
use ReentrantLock replace sysnchronized. for ali jvm fiber wisp
This commit is contained in:
@@ -24,6 +24,8 @@ import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.filter.FilterChain;
|
||||
@@ -69,6 +71,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
|
||||
public final static String ATTR_TRANSACTION = "stat.tx";
|
||||
public final static String ATTR_RESULTSET_CLOSED = "stat.rs.closed";
|
||||
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
// protected JdbcDataSourceStat dataSourceStat;
|
||||
|
||||
@Deprecated
|
||||
@@ -151,13 +155,18 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(DataSourceProxy dataSource) {
|
||||
if (this.dbType == null || this.dbType.trim().length() == 0) {
|
||||
this.dbType = dataSource.getDbType();
|
||||
}
|
||||
public void init(DataSourceProxy dataSource) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (this.dbType == null || this.dbType.trim().length() == 0) {
|
||||
this.dbType = dataSource.getDbType();
|
||||
}
|
||||
|
||||
configFromProperties(dataSource.getConnectProperties());
|
||||
configFromProperties(System.getProperties());
|
||||
configFromProperties(dataSource.getConnectProperties());
|
||||
configFromProperties(System.getProperties());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void configFromProperties(Properties properties) {
|
||||
|
||||
@@ -231,6 +231,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
protected Condition notEmpty;
|
||||
protected Condition empty;
|
||||
|
||||
protected ReentrantLock activeConnectionLock = new ReentrantLock();
|
||||
|
||||
protected AtomicLong createCount = new AtomicLong();
|
||||
protected AtomicLong destroyCount = new AtomicLong();
|
||||
|
||||
@@ -1372,8 +1374,11 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
}
|
||||
|
||||
public Set<DruidPooledConnection> getActiveConnections() {
|
||||
synchronized (activeConnections) {
|
||||
activeConnectionLock.lock();
|
||||
try {
|
||||
return new HashSet<DruidPooledConnection>(this.activeConnections.keySet());
|
||||
} finally {
|
||||
activeConnectionLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* @author wenshao [szujobs@hotmail.com]
|
||||
|
||||
@@ -1007,7 +1007,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //
|
||||
|| realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {
|
||||
this.validConnectionChecker = new MySqlValidConnectionChecker();
|
||||
} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)) {
|
||||
} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
|
||||
|| realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
|
||||
this.validConnectionChecker = new OracleValidConnectionChecker();
|
||||
} else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)
|
||||
|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)
|
||||
@@ -1141,8 +1142,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
poolableConnection.setConnectedTimeNano();
|
||||
poolableConnection.setTraceEnable(true);
|
||||
|
||||
synchronized (activeConnections) {
|
||||
activeConnectionLock.lock();
|
||||
try {
|
||||
activeConnections.put(poolableConnection, PRESENT);
|
||||
} finally {
|
||||
activeConnectionLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,21 +1293,28 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
// exceptionSorter.isExceptionFatal
|
||||
if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) {
|
||||
if (pooledConnection.isTraceEnable()) {
|
||||
synchronized (activeConnections) {
|
||||
activeConnectionLock.lock();
|
||||
try {
|
||||
if (pooledConnection.isTraceEnable()) {
|
||||
activeConnections.remove(pooledConnection);
|
||||
pooledConnection.setTraceEnable(false);
|
||||
}
|
||||
} finally {
|
||||
activeConnectionLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
boolean requireDiscard = false;
|
||||
synchronized (pooledConnection) {
|
||||
final ReentrantLock lock = pooledConnection.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if ((!pooledConnection.isClosed()) || !pooledConnection.isDisable()) {
|
||||
holder.setDiscard(true);
|
||||
pooledConnection.disable(t);
|
||||
requireDiscard = true;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
if (requireDiscard) {
|
||||
@@ -1341,16 +1352,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
final Connection physicalConnection = holder.getConnection();
|
||||
|
||||
if (pooledConnection.isTraceEnable()) {
|
||||
synchronized (activeConnections) {
|
||||
Object oldInfo = null;
|
||||
activeConnectionLock.lock();
|
||||
try {
|
||||
if (pooledConnection.isTraceEnable()) {
|
||||
Object oldInfo = activeConnections.remove(pooledConnection);
|
||||
if (oldInfo == null) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
|
||||
}
|
||||
}
|
||||
oldInfo = activeConnections.remove(pooledConnection);
|
||||
pooledConnection.setTraceEnable(false);
|
||||
}
|
||||
} finally {
|
||||
activeConnectionLock.unlock();
|
||||
}
|
||||
if (oldInfo == null) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1367,8 +1382,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
// reset holder, restore default settings, clear warnings
|
||||
boolean isSameThread = pooledConnection.getOwnerThread() == Thread.currentThread();
|
||||
if (!isSameThread) {
|
||||
synchronized (pooledConnection) {
|
||||
final ReentrantLock lock = pooledConnection.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
holder.reset();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
} else {
|
||||
holder.reset();
|
||||
@@ -2212,7 +2231,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
|
||||
|
||||
synchronized (activeConnections) {
|
||||
activeConnectionLock.lock();
|
||||
try {
|
||||
Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
|
||||
|
||||
for (; iter.hasNext();) {
|
||||
@@ -2230,14 +2250,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
abandonedList.add(pooledConnection);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
activeConnectionLock.unlock();
|
||||
}
|
||||
|
||||
if (abandonedList.size() > 0) {
|
||||
for (DruidPooledConnection pooledConnection : abandonedList) {
|
||||
synchronized (pooledConnection) {
|
||||
final ReentrantLock lock = pooledConnection.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (pooledConnection.isDisable()) {
|
||||
continue;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
JdbcUtils.close(pooledConnection);
|
||||
|
||||
@@ -35,6 +35,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.sql.ConnectionEvent;
|
||||
import javax.sql.ConnectionEventListener;
|
||||
@@ -75,6 +77,8 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
|
||||
|
||||
private Throwable disableError = null;
|
||||
|
||||
public ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
public DruidPooledConnection(DruidConnectionHolder holder){
|
||||
super(holder.getConnection());
|
||||
|
||||
@@ -258,33 +262,38 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
|
||||
this.disable = true;
|
||||
}
|
||||
|
||||
public synchronized void syncClose() throws SQLException {
|
||||
if (this.disable) {
|
||||
return;
|
||||
}
|
||||
|
||||
DruidConnectionHolder holder = this.holder;
|
||||
if (holder == null) {
|
||||
if (dupCloseLogEnable) {
|
||||
LOG.error("dup close");
|
||||
public void syncClose() throws SQLException {
|
||||
lock.lock();
|
||||
try {
|
||||
if (this.disable) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (ConnectionEventListener listener : holder.getConnectionEventListeners()) {
|
||||
listener.connectionClosed(new ConnectionEvent(this));
|
||||
}
|
||||
DruidConnectionHolder holder = this.holder;
|
||||
if (holder == null) {
|
||||
if (dupCloseLogEnable) {
|
||||
LOG.error("dup close");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DruidAbstractDataSource dataSource = holder.getDataSource();
|
||||
List<Filter> filters = dataSource.getProxyFilters();
|
||||
if (filters.size() > 0) {
|
||||
FilterChainImpl filterChain = new FilterChainImpl(dataSource);
|
||||
filterChain.dataSource_recycle(this);
|
||||
} else {
|
||||
recycle();
|
||||
}
|
||||
for (ConnectionEventListener listener : holder.getConnectionEventListeners()) {
|
||||
listener.connectionClosed(new ConnectionEvent(this));
|
||||
}
|
||||
|
||||
this.disable = true;
|
||||
DruidAbstractDataSource dataSource = holder.getDataSource();
|
||||
List<Filter> filters = dataSource.getProxyFilters();
|
||||
if (filters.size() > 0) {
|
||||
FilterChainImpl filterChain = new FilterChainImpl(dataSource);
|
||||
filterChain.dataSource_recycle(this);
|
||||
} else {
|
||||
recycle();
|
||||
}
|
||||
|
||||
this.disable = true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void recycle() throws SQLException {
|
||||
@@ -1106,8 +1115,11 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
|
||||
}
|
||||
|
||||
if (asyncCloseEnabled) {
|
||||
synchronized (this) {
|
||||
lock.lock();
|
||||
try {
|
||||
checkStateInternal();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
} else {
|
||||
checkStateInternal();
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.management.JMException;
|
||||
import javax.management.MBeanServer;
|
||||
@@ -44,6 +46,8 @@ import com.alibaba.druid.util.JMXUtils;
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBean {
|
||||
|
||||
private final static Lock staticLock = new ReentrantLock();
|
||||
|
||||
public final static String SYS_PROP_INSTANCES = "druid.dataSources";
|
||||
public final static String SYS_PROP_REGISTER_SYS_PROPERTY = "druid.registerToSysProperty";
|
||||
|
||||
@@ -62,23 +66,28 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
return instance;
|
||||
}
|
||||
|
||||
public synchronized static void clear() {
|
||||
Map<Object, ObjectName> dataSources = getInstances();
|
||||
public static void clear() {
|
||||
staticLock.lock();
|
||||
try {
|
||||
Map<Object, ObjectName> dataSources = getInstances();
|
||||
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
for (Object item : dataSources.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) item;
|
||||
ObjectName objectName = (ObjectName) entry.getValue();
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
for (Object item : dataSources.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) item;
|
||||
ObjectName objectName = (ObjectName) entry.getValue();
|
||||
|
||||
if (objectName == null) {
|
||||
continue;
|
||||
}
|
||||
if (objectName == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
mbeanServer.unregisterMBean(objectName);
|
||||
} catch (JMException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
try {
|
||||
mbeanServer.unregisterMBean(objectName);
|
||||
} catch (JMException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
staticLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +95,8 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
public static Map<Object, ObjectName> getInstances() {
|
||||
Map<Object, ObjectName> tmp = dataSources;
|
||||
if (tmp == null) {
|
||||
synchronized (DruidDataSourceStatManager.class) {
|
||||
staticLock.lock();
|
||||
try {
|
||||
if (isRegisterToSystemProperty()) {
|
||||
dataSources = getInstances0();
|
||||
} else {
|
||||
@@ -95,6 +105,8 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
dataSources = tmp = Collections.synchronizedMap(new IdentityHashMap<Object, ObjectName>());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
staticLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user