mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
format code
This commit is contained in:
@@ -238,10 +238,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
<version>2.0</version>
|
||||
<version>2.5.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.ibatis</groupId>
|
||||
<artifactId>ibatis-sqlmap</artifactId>
|
||||
<version>2.3.4.726</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
@@ -348,12 +363,6 @@
|
||||
<version>0.7.1-rc2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jolbox</groupId>
|
||||
<artifactId>bonecp-test-commons</artifactId>
|
||||
<version>0.7.1-rc2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>proxool</groupId>
|
||||
|
||||
@@ -301,6 +301,14 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
|
||||
connectionLog("connect commited. id " + connection.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connection_setAutoCommit(FilterChain chain, ConnectionProxy connection, boolean autoCommit)
|
||||
throws SQLException {
|
||||
|
||||
connectionLog("connect setAutoComment " + autoCommit + ". id " + connection.getId());
|
||||
chain.connection_setAutoCommit(connection, autoCommit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connection_close(FilterChain chain, ConnectionProxy connection) throws SQLException {
|
||||
|
||||
@@ -488,9 +488,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
|
||||
|
||||
String sql = resultSet.getSql();
|
||||
if (sql != null) {
|
||||
JdbcSqlStat sqlStat = getSqlStat(sql);
|
||||
JdbcSqlStat sqlStat = resultSet.getSqlStat();
|
||||
if (sqlStat != null) {
|
||||
sqlStat.addFetchRowCount(fetchCount);
|
||||
sqlStat.addResultSetHoldTimeNano(nanoSpan);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.alibaba.druid.proxy.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
*/
|
||||
@@ -27,6 +29,8 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy {
|
||||
StatementProxy getStatementProxy();
|
||||
|
||||
String getSql();
|
||||
|
||||
JdbcSqlStat getSqlStat();
|
||||
|
||||
int getCursorIndex();
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.filter.FilterChain;
|
||||
import com.alibaba.druid.filter.FilterChainImpl;
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
@@ -53,12 +54,14 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
|
||||
protected int cursorIndex = 0;
|
||||
protected int fetchRowCount = 0;
|
||||
protected long constructNano;
|
||||
protected final JdbcSqlStat sqlStat;
|
||||
|
||||
public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){
|
||||
super(resultSet, id);
|
||||
this.statement = statement;
|
||||
this.resultSet = resultSet;
|
||||
this.sql = sql;
|
||||
sqlStat = this.statement.getSqlStat();
|
||||
}
|
||||
|
||||
public long getConstructNano() {
|
||||
@@ -68,7 +71,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
|
||||
public void setConstructNano(long constructNano) {
|
||||
this.constructNano = constructNano;
|
||||
}
|
||||
|
||||
|
||||
public void setConstructNano() {
|
||||
if (this.constructNano <= 0) {
|
||||
this.constructNano = System.nanoTime();
|
||||
@@ -87,6 +90,10 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
|
||||
return sql;
|
||||
}
|
||||
|
||||
public JdbcSqlStat getSqlStat() {
|
||||
return sqlStat;
|
||||
}
|
||||
|
||||
public ResultSet getResultSetRaw() {
|
||||
return resultSet;
|
||||
}
|
||||
@@ -1061,7 +1068,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
|
||||
if (iface == ResultSet.class) {
|
||||
return (T) resultSet;
|
||||
}
|
||||
|
||||
|
||||
return super.unwrap(iface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
if (dataSources.size() == 0) {
|
||||
try {
|
||||
|
||||
|
||||
ObjectName objectName = new ObjectName(MBEAN_NAME);
|
||||
if (!mbeanServer.isRegistered(objectName)) {
|
||||
mbeanServer.registerMBean(instance, objectName);
|
||||
@@ -98,9 +98,9 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
|
||||
public synchronized static void remove(DruidDataSource dataSource) {
|
||||
ObjectName objectName = dataSources.remove(dataSource);
|
||||
|
||||
|
||||
if (objectName == null) {
|
||||
objectName = dataSource.getObjectName();
|
||||
objectName = dataSource.getObjectName();
|
||||
}
|
||||
|
||||
if (objectName == null) {
|
||||
@@ -164,54 +164,63 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
// 0 - 4
|
||||
map.put("Name", dataSource.getName());
|
||||
map.put("URL", dataSource.getUrl());
|
||||
map.put("CreateCount", dataSource.getCreateCount());
|
||||
map.put("DestroyCount", dataSource.getDestroyCount());
|
||||
map.put("ConnectCount", dataSource.getConnectCount());
|
||||
|
||||
// 5 - 9
|
||||
map.put("CloseCount", dataSource.getCloseCount());
|
||||
map.put("ActiveCount", dataSource.getActivePeak());
|
||||
map.put("PoolingCount", dataSource.getPoolingCount());
|
||||
map.put("LockQueueLength", dataSource.getLockQueueLength());
|
||||
map.put("WaitThreadCount", dataSource.getNotEmptyWaitThreadPeak());
|
||||
|
||||
// 10 - 14
|
||||
map.put("InitialSize", dataSource.getInitialSize());
|
||||
map.put("MaxActive", dataSource.getMaxActive());
|
||||
map.put("MinIdle", dataSource.getMinIdle());
|
||||
map.put("PoolPreparedStatements", dataSource.isPoolPreparedStatements());
|
||||
map.put("TestOnBorrow", dataSource.isTestOnBorrow());
|
||||
|
||||
// 15 - 19
|
||||
map.put("TestOnReturn", dataSource.isTestOnReturn());
|
||||
map.put("MinEvictableIdleTimeMillis", dataSource.getMinEvictableIdleTimeMillis());
|
||||
map.put("ConnectErrorCount", dataSource.getConnectErrorCount());
|
||||
map.put("CreateTimespanMillis", dataSource.getCreateTimespanMillis());
|
||||
map.put("DbType", dataSource.getDbType());
|
||||
|
||||
// 20 - 24
|
||||
map.put("ValidationQuery", dataSource.getValidationQuery());
|
||||
map.put("ValidationQueryTimeout", dataSource.getValidationQueryTimeout());
|
||||
map.put("DriverClassName", dataSource.getDriverClassName());
|
||||
map.put("Username", dataSource.getUsername());
|
||||
map.put("RemoveAbandonedCount", dataSource.getRemoveAbandonedCount());
|
||||
|
||||
// 25 - 29
|
||||
map.put("NotEmptyWaitCount", dataSource.getNotEmptyWaitCount());
|
||||
map.put("NotEmptyWaitNanos", dataSource.getNotEmptyWaitNanos());
|
||||
map.put("ErrorCount", dataSource.getErrorCount());
|
||||
map.put("ReusePreparedStatementCount", dataSource.getCachedPreparedStatementHitCount());
|
||||
map.put("StartTransactionCount", dataSource.getStartTransactionCount());
|
||||
|
||||
// 30 - 34
|
||||
map.put("CommitCount", dataSource.getCommitCount());
|
||||
map.put("RollbackCount", dataSource.getRollbackCount());
|
||||
map.put("LastError", JMXUtils.getErrorCompositeData(dataSource.getLastError()));
|
||||
map.put("LastCreateError", JMXUtils.getErrorCompositeData(dataSource.getLastCreateError()));
|
||||
map.put("PreparedStatementCacheDeleteCount", dataSource.getCachedPreparedStatementDeleteCount());
|
||||
|
||||
|
||||
// 35 - 39
|
||||
map.put("PreparedStatementCacheAccessCount", dataSource.getCachedPreparedStatementAccessCount());
|
||||
map.put("PreparedStatementCacheMissCount", dataSource.getCachedPreparedStatementMissCount());
|
||||
map.put("PreparedStatementCacheHitCount", dataSource.getCachedPreparedStatementHitCount());
|
||||
map.put("PreparedStatementCacheCurrentCount", dataSource.getCachedPreparedStatementCount());
|
||||
map.put("Version", dataSource.getVersion());
|
||||
|
||||
// 40 -
|
||||
map.put("LastErrorTime", dataSource.getLastErrorTime());
|
||||
map.put("LastCreateErrorTime", dataSource.getLastCreateErrorTime());
|
||||
map.put("CreateErrorCount", dataSource.getCreateErrorCount());
|
||||
@@ -228,36 +237,130 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
|
||||
}
|
||||
|
||||
OpenType<?>[] indexTypes = new OpenType<?>[] {
|
||||
//
|
||||
SimpleType.STRING, SimpleType.STRING, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, //
|
||||
SimpleType.LONG, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.BOOLEAN, //
|
||||
SimpleType.BOOLEAN, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.STRING, //
|
||||
SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING, SimpleType.LONG, //
|
||||
SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG//
|
||||
, SimpleType.LONG, SimpleType.LONG, JMXUtils.getThrowableCompositeType(), JMXUtils.getThrowableCompositeType(), SimpleType.LONG //
|
||||
, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.STRING //
|
||||
, SimpleType.DATE , SimpleType.DATE, SimpleType.LONG
|
||||
// 0 - 4
|
||||
SimpleType.STRING, //
|
||||
SimpleType.STRING, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
|
||||
// 5 - 9
|
||||
SimpleType.LONG, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, //
|
||||
|
||||
// 10 - 14
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.BOOLEAN, //
|
||||
SimpleType.BOOLEAN, //
|
||||
|
||||
// 15 - 19
|
||||
SimpleType.BOOLEAN, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.STRING, //
|
||||
|
||||
// 20 - 24
|
||||
SimpleType.STRING, //
|
||||
SimpleType.INTEGER, //
|
||||
SimpleType.STRING, //
|
||||
SimpleType.STRING, //
|
||||
SimpleType.LONG, //
|
||||
|
||||
// 25 - 29
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
|
||||
// 30 - 34
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
JMXUtils.getThrowableCompositeType(), //
|
||||
JMXUtils.getThrowableCompositeType(), //
|
||||
SimpleType.LONG, //
|
||||
|
||||
// 35 - 39
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.STRING, //
|
||||
|
||||
// 40 -
|
||||
SimpleType.DATE, //
|
||||
SimpleType.DATE, //
|
||||
SimpleType.LONG //
|
||||
//
|
||||
};
|
||||
|
||||
String[] indexNames = {
|
||||
//
|
||||
"Name", "URL", "CreateCount", "DestroyCount",
|
||||
// 0 - 4
|
||||
"Name", //
|
||||
"URL", //
|
||||
"CreateCount", //
|
||||
"DestroyCount", //
|
||||
"ConnectCount", //
|
||||
"CloseCount", "ActiveCount", "PoolingCount", "LockQueueLength",
|
||||
|
||||
// 5 - 9
|
||||
"CloseCount", //
|
||||
"ActiveCount", //
|
||||
"PoolingCount", //
|
||||
"LockQueueLength", //
|
||||
"WaitThreadCount", //
|
||||
"InitialSize", "MaxActive", "MinIdle", "PoolPreparedStatements",
|
||||
|
||||
// 10 - 14
|
||||
"InitialSize", //
|
||||
"MaxActive", //
|
||||
"MinIdle", //
|
||||
"PoolPreparedStatements", //
|
||||
"TestOnBorrow", //
|
||||
"TestOnReturn", "MinEvictableIdleTimeMillis", "ConnectErrorCount", "CreateTimespanMillis",
|
||||
|
||||
// 15 - 19
|
||||
"TestOnReturn", //
|
||||
"MinEvictableIdleTimeMillis", //
|
||||
"ConnectErrorCount", //
|
||||
"CreateTimespanMillis", //
|
||||
"DbType", //
|
||||
"ValidationQuery", "ValidationQueryTimeout", "DriverClassName", "Username",
|
||||
|
||||
// 20 - 24
|
||||
"ValidationQuery", //
|
||||
"ValidationQueryTimeout", //
|
||||
"DriverClassName", //
|
||||
"Username", //
|
||||
"RemoveAbandonedCount", //
|
||||
"NotEmptyWaitCount", "NotEmptyWaitNanos", "ErrorCount", "ReusePreparedStatementCount",
|
||||
|
||||
// 25 - 29
|
||||
"NotEmptyWaitCount", //
|
||||
"NotEmptyWaitNanos", //
|
||||
"ErrorCount", //
|
||||
"ReusePreparedStatementCount", //
|
||||
"StartTransactionCount", //
|
||||
"CommitCount", "RollbackCount", "LastError", "LastCreateError", "PreparedStatementCacheDeleteCount" //
|
||||
, "PreparedStatementCacheAccessCount", "PreparedStatementCacheMissCount", "PreparedStatementCacheHitCount", "PreparedStatementCacheCurrentCount", "Version" //
|
||||
, "LastErrorTime", "LastCreateErrorTime", "CreateErrorCount"
|
||||
|
||||
// 30 - 34
|
||||
"CommitCount", //
|
||||
"RollbackCount", //
|
||||
"LastError", //
|
||||
"LastCreateError", //
|
||||
"PreparedStatementCacheDeleteCount", //
|
||||
|
||||
// 35 - 39
|
||||
"PreparedStatementCacheAccessCount", //
|
||||
"PreparedStatementCacheMissCount", //
|
||||
"PreparedStatementCacheHitCount", //
|
||||
"PreparedStatementCacheCurrentCount", //
|
||||
"Version" //
|
||||
|
||||
// 40 -
|
||||
, "LastErrorTime", //
|
||||
"LastCreateErrorTime", //
|
||||
"CreateErrorCount" //
|
||||
//
|
||||
};
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
private final AtomicLong executeSpanNanoMax = new AtomicLong();
|
||||
private final AtomicLong runningCount = new AtomicLong(0L);
|
||||
private final AtomicLong concurrentMax = new AtomicLong();
|
||||
private final AtomicLong resultSetHoldTimeNano = new AtomicLong();
|
||||
|
||||
private String name;
|
||||
private String file;
|
||||
private String dbType;
|
||||
@@ -180,6 +182,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
histogram.reset();
|
||||
this.lastSlowParameters = null;
|
||||
inTransactionCount.set(0);
|
||||
resultSetHoldTimeNano.set(0);
|
||||
}
|
||||
|
||||
public long getConcurrentMax() {
|
||||
@@ -393,6 +396,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
// 25 -
|
||||
new ArrayType<Long>(SimpleType.LONG, true), //
|
||||
SimpleType.STRING, //
|
||||
SimpleType.LONG, //
|
||||
};
|
||||
|
||||
String[] indexNames = {
|
||||
@@ -433,7 +437,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
|
||||
// 25 -
|
||||
"Histogram", //
|
||||
"LastSlowParameters"
|
||||
"LastSlowParameters",
|
||||
"ResultSetHoldTime"
|
||||
//
|
||||
};
|
||||
String[] indexDescriptions = indexNames;
|
||||
@@ -455,30 +460,33 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
map.put("SQL", sql);
|
||||
map.put("ExecuteCount", getExecuteCount());
|
||||
map.put("ErrorCount", getErrorCount());
|
||||
map.put("TotalTime", getExecuteMillisTotal());
|
||||
|
||||
// 5 - 9
|
||||
map.put("TotalTime", getExecuteMillisTotal());
|
||||
map.put("LastTime", getExecuteLastStartTime());
|
||||
map.put("MaxTimespan", getExecuteMillisMax());
|
||||
map.put("LastError", JMXUtils.getErrorCompositeData(this.getExecuteErrorLast()));
|
||||
map.put("EffectedRowCount", getUpdateCount());
|
||||
map.put("FetchRowCount", getFetchRowCount());
|
||||
|
||||
// 10 - 14
|
||||
map.put("FetchRowCount", getFetchRowCount());
|
||||
map.put("MaxTimespanOccurTime", getExecuteNanoSpanMaxOccurTime());
|
||||
map.put("BatchSizeMax", getExecuteBatchSizeMax());
|
||||
map.put("BatchSizeTotal", getExecuteBatchSizeTotal());
|
||||
map.put("ConcurrentMax", getConcurrentMax());
|
||||
map.put("RunningCount", getRunningCount());
|
||||
|
||||
map.put("Name", getName());
|
||||
map.put("File", getFile());
|
||||
// 15 -
|
||||
map.put("RunningCount", getRunningCount()); // 15
|
||||
map.put("Name", getName()); // 16
|
||||
map.put("File", getFile()); // 17
|
||||
|
||||
Throwable lastError = this.executeErrorLast;
|
||||
if (lastError != null) {
|
||||
map.put("LastErrorMessage", lastError.getMessage());
|
||||
map.put("LastErrorClass", lastError.getClass().getName());
|
||||
map.put("LastErrorMessage", lastError.getMessage()); // 18
|
||||
map.put("LastErrorClass", lastError.getClass().getName()); // 19
|
||||
|
||||
map.put("LastErrorStackTrace", IOUtils.getStackTrace(lastError));
|
||||
map.put("LastErrorTime", new Date(executeErrorLastTime));
|
||||
map.put("LastErrorStackTrace", IOUtils.getStackTrace(lastError)); // 20
|
||||
map.put("LastErrorTime", new Date(executeErrorLastTime)); // 21
|
||||
} else {
|
||||
map.put("LastErrorMessage", null);
|
||||
map.put("LastErrorClass", null);
|
||||
@@ -486,13 +494,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
map.put("LastErrorTime", null);
|
||||
}
|
||||
|
||||
map.put("DbType", dbType);
|
||||
map.put("URL", null);
|
||||
map.put("InTransactionCount", getInTransactionCount());
|
||||
map.put("DbType", dbType); // 22
|
||||
map.put("URL", null); // 23
|
||||
map.put("InTransactionCount", getInTransactionCount()); // 24
|
||||
|
||||
map.put("Histogram", this.histogram.toArray());
|
||||
|
||||
map.put("LastSlowParameters", lastSlowParameters);
|
||||
map.put("Histogram", this.histogram.toArray()); // 25
|
||||
map.put("LastSlowParameters", lastSlowParameters); // 26
|
||||
map.put("ResultSetHoldTime", getResultSetHoldTimeMilis()); // 26
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -511,4 +519,17 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
executeErrorLast = error;
|
||||
|
||||
}
|
||||
|
||||
public long getResultSetHoldTimeMilis() {
|
||||
return getResultSetHoldTimeNano() / (1000 * 1000);
|
||||
}
|
||||
|
||||
public long getResultSetHoldTimeNano() {
|
||||
return resultSetHoldTimeNano.get();
|
||||
}
|
||||
|
||||
public void addResultSetHoldTimeNano(long nano) {
|
||||
resultSetHoldTimeNano.addAndGet(nano);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import com.alibaba.druid.filter.FilterAdapter;
|
||||
import com.alibaba.druid.filter.FilterChain;
|
||||
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
|
||||
import com.alibaba.druid.spring.IUserService;
|
||||
import com.alibaba.druid.spring.User;
|
||||
import com.alibaba.druid.stat.DruidDataSourceStatManager;
|
||||
|
||||
public class SpringFilterTest extends TestCase {
|
||||
@@ -35,17 +37,37 @@ public class SpringFilterTest extends TestCase {
|
||||
"com/alibaba/druid/pool/spring-config-1.xml");
|
||||
|
||||
DataSource dataSource = (DataSource) context.getBean("dataSource");
|
||||
Connection conn = dataSource.getConnection();
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("select 1");
|
||||
stmt.execute("select 2");
|
||||
stmt.execute("select 1");
|
||||
stmt.close();
|
||||
conn.close();
|
||||
{
|
||||
Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("CREATE TABLE sequence_seed (value INTEGER, name VARCHAR(50))");
|
||||
stmt.close();
|
||||
conn.close();
|
||||
}
|
||||
{
|
||||
Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("CREATE TABLE t_User (id BIGINT, name VARCHAR(50))");
|
||||
stmt.close();
|
||||
conn.close();
|
||||
}
|
||||
{
|
||||
Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("insert into sequence_seed (value ,name) values (0, 'druid-spring-test')");
|
||||
stmt.close();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
// user-service
|
||||
IUserService service = (IUserService) context.getBean("user-service");
|
||||
User user = new User();
|
||||
user.setName("xx");
|
||||
service.addUser(user);
|
||||
|
||||
TestFilter filter = (TestFilter) context.getBean("test-filter");
|
||||
Assert.assertEquals(1, filter.getConnectCount());
|
||||
Assert.assertEquals(2, filter.getConnectCount());
|
||||
|
||||
context.close();
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
public interface ISequenceDao {
|
||||
|
||||
boolean compareAndSet(String name, int value, int expect);
|
||||
|
||||
int getValue(String name);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
|
||||
public interface ISequenceService {
|
||||
long nextValue();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
|
||||
public interface IUserDao {
|
||||
void addUser(User user);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
|
||||
public interface IUserService {
|
||||
void addUser(User user);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
|
||||
|
||||
public class SequenceDao extends SqlMapClientDaoSupport implements ISequenceDao {
|
||||
|
||||
public boolean compareAndSet(String name, int value, int expect) {
|
||||
|
||||
Map<String, Object> parameters = new HashMap<String, Object>();
|
||||
parameters.put("name", name);
|
||||
parameters.put("value", value);
|
||||
parameters.put("expect", expect);
|
||||
|
||||
int updateCount = getSqlMapClientTemplate().update("Sequence.compareAndSet", parameters);
|
||||
|
||||
return updateCount == 1;
|
||||
}
|
||||
|
||||
public int getValue(String name) {
|
||||
return (Integer) getSqlMapClientTemplate().queryForObject("Sequence.getValue", name);
|
||||
}
|
||||
|
||||
public int getValueForUpdate(String name) {
|
||||
return (Integer) getSqlMapClientTemplate().queryForObject("Sequence.getValueForUpdate", name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class SequenceService implements SequenceServiceMBean, ISequenceService {
|
||||
|
||||
private ISequenceDao dao;
|
||||
private String name = "druid-spring-test";
|
||||
|
||||
private String seed;
|
||||
|
||||
private AtomicInteger increment = new AtomicInteger();
|
||||
|
||||
public ISequenceDao getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
public void setDao(ISequenceDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public long nextValue() {
|
||||
if (seed == null) {
|
||||
init();
|
||||
}
|
||||
|
||||
int value = increment.getAndIncrement();
|
||||
|
||||
String text = seed + "9" + Integer.toString(value);
|
||||
|
||||
return Long.parseLong(text);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public synchronized void init() {
|
||||
this.seed = nextSeed();
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public synchronized String nextSeed() {
|
||||
for (;;) {
|
||||
int value = dao.getValue(name);
|
||||
if (dao.compareAndSet(name, value + 1, value)) {
|
||||
if (value == 0) {
|
||||
return "";
|
||||
} else {
|
||||
return Integer.toString(value, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
|
||||
public interface SequenceServiceMBean {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
public class User {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
|
||||
|
||||
public class UserDao extends SqlMapClientDaoSupport implements IUserDao {
|
||||
|
||||
public void addUser(User user) {
|
||||
getSqlMapClientTemplate().insert("User.insert", user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.alibaba.druid.spring;
|
||||
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class UserService implements IUserService {
|
||||
|
||||
private IUserDao dao;
|
||||
private ISequenceService sequenceService;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public void addUser(User user) {
|
||||
user.setId(sequenceService.nextValue());
|
||||
dao.addUser(user);
|
||||
}
|
||||
|
||||
public IUserDao getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
public void setDao(IUserDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
public ISequenceService getSequenceService() {
|
||||
return sequenceService;
|
||||
}
|
||||
|
||||
public void setSequenceService(ISequenceService sequenceService) {
|
||||
this.sequenceService = sequenceService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE sqlMap
|
||||
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
||||
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
||||
<sqlMap namespace="Sequence">
|
||||
<select id="getValue" resultClass="int" parameterClass="string">
|
||||
SELECT value
|
||||
FROM sequence_seed
|
||||
WHERE name = #name#
|
||||
</select>
|
||||
|
||||
<select id="getValueForUpdate" resultClass="int" parameterClass="string">
|
||||
SELECT value
|
||||
FROM sequence_seed
|
||||
WHERE name = #name#
|
||||
FOR UPDATE
|
||||
</select>
|
||||
|
||||
<update id="compareAndSet">
|
||||
UPDATE sequence_seed
|
||||
SET value = #value#
|
||||
WHERE name = #name# AND value = #expect#
|
||||
</update>
|
||||
</sqlMap>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE sqlMap
|
||||
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
||||
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
||||
<sqlMap namespace="User">
|
||||
<typeAlias alias="User" type="com.alibaba.druid.spring.User" />
|
||||
|
||||
<update id="insert" parameterClass="User">
|
||||
insert into t_User (id, name) values (#id#, #name#)
|
||||
</update>
|
||||
</sqlMap>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
|
||||
<sqlMapConfig>
|
||||
<settings cacheModelsEnabled="true" enhancementEnabled="true"
|
||||
lazyLoadingEnabled="true" maxRequests="512" maxSessions="128"
|
||||
maxTransactions="32" useStatementNamespaces="true" />
|
||||
<sqlMap resource="com/alibaba/druid/pool/Sequence.xml" />
|
||||
<sqlMap resource="com/alibaba/druid/pool/User.xml" />
|
||||
</sqlMapConfig>
|
||||
@@ -6,6 +6,28 @@
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
|
||||
default-lazy-init="false">
|
||||
|
||||
<bean class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
|
||||
id="master-sqlMapClient">
|
||||
<property name="configLocation" value="com/alibaba/druid/pool/ibatis-config-druid-test.xml" />
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="sequence-dao" class="com.alibaba.druid.spring.SequenceDao">
|
||||
<property name="sqlMapClient" ref="master-sqlMapClient" />
|
||||
</bean>
|
||||
<bean id="sequence-service" class="com.alibaba.druid.spring.SequenceService">
|
||||
<property name="dao" ref="sequence-dao" />
|
||||
</bean>
|
||||
|
||||
<bean id="user-dao" class="com.alibaba.druid.spring.UserDao">
|
||||
<property name="sqlMapClient" ref="master-sqlMapClient" />
|
||||
</bean>
|
||||
<bean id="user-service" class="com.alibaba.druid.spring.UserService">
|
||||
<property name="dao" ref="user-dao" />
|
||||
<property name="sequenceService" ref="sequence-service" />
|
||||
</bean>
|
||||
<!-- -->
|
||||
|
||||
<bean id="test-filter" class="com.alibaba.druid.bvt.pool.SpringFilterTest$TestFilter">
|
||||
</bean>
|
||||
@@ -15,6 +37,7 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/
|
||||
<bean id="wall-filter-config" class="com.alibaba.druid.wall.WallConfig"
|
||||
init-method="init">
|
||||
<property name="dir" value="META-INF/druid/wall/mysql" />
|
||||
<property name="noneBaseStatementAllow" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">
|
||||
@@ -25,7 +48,7 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/
|
||||
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
|
||||
init-method="init" destroy-method="close">
|
||||
<property name="url">
|
||||
<value>jdbc:mock:</value>
|
||||
<value>jdbc:derby:memory:spring-test;create=true</value>
|
||||
</property>
|
||||
<property name="initialSize">
|
||||
<value>1</value>
|
||||
@@ -40,6 +63,7 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/
|
||||
<ref bean="wall-filter" />
|
||||
</list>
|
||||
</property>
|
||||
<property name="filters" value="log4j" />
|
||||
</bean>
|
||||
|
||||
<bean id="mbeanServer" class="com.alibaba.druid.spring.MBeanServerFactoryBean" />
|
||||
@@ -58,4 +82,11 @@ http://www.springframework.org/schema/aop http://www.springframework.org/schema/
|
||||
</property>
|
||||
<property name="server" ref="mbeanServer" />
|
||||
</bean>
|
||||
|
||||
<bean id="txManager-druid-test"
|
||||
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven transaction-manager="txManager-druid-test" proxy-target-class="false" />
|
||||
</beans>
|
||||
|
||||
@@ -22,8 +22,7 @@ log4j.category.org.apache.catalina=ERROR
|
||||
log4j.category.org.apache.struts.chain=ERROR
|
||||
log4j.category.org.apache.jasper=INFO
|
||||
log4j.category.org.apache.struts=INFO
|
||||
log4j.category.java.sql=DEBUG
|
||||
log4j.category.java.sql.ResultSet=DEBUG
|
||||
log4j.category.java.sql=ERROR
|
||||
log4j.category.org.codehaus.xfire=INFO
|
||||
log4j.category.httpclient=INFO
|
||||
log4j.category.org.apache.struts.action.ActionServlet=ERROR
|
||||
|
||||
Reference in New Issue
Block a user