mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
No effective change - format only
This commit is contained in:
@@ -17,187 +17,185 @@ import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadVal
|
||||
* and this allows for fast addition and removal (by slotId without looping).
|
||||
* The capacity will increase on demand by the 'growBy' amount.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author rbygrave
|
||||
*
|
||||
*/
|
||||
class BusyConnectionBuffer {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BusyConnectionBuffer.class);
|
||||
|
||||
private PooledConnection[] slots;
|
||||
|
||||
private final int growBy;
|
||||
|
||||
private int size;
|
||||
|
||||
private int pos = -1;
|
||||
|
||||
/**
|
||||
* Create the buffer with an initial capacity and fixed growBy.
|
||||
* We generally do not want the buffer to grow very often.
|
||||
*
|
||||
* @param capacity
|
||||
* the initial capacity
|
||||
* @param growBy
|
||||
* the fixed amount to grow the buffer by.
|
||||
*/
|
||||
protected BusyConnectionBuffer(int capacity, int growBy) {
|
||||
this.slots = new PooledConnection[capacity];
|
||||
this.growBy = growBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* We can only grow (not shrink) the capacity.
|
||||
*/
|
||||
protected void setCapacity(int newCapacity) {
|
||||
if (newCapacity > slots.length){
|
||||
PooledConnection[] current = this.slots;
|
||||
this.slots = new PooledConnection[newCapacity];
|
||||
System.arraycopy(current, 0, this.slots, 0, current.length);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Arrays.toString(slots);
|
||||
}
|
||||
|
||||
protected int getCapacity() {
|
||||
return slots.length;
|
||||
}
|
||||
|
||||
protected int size(){
|
||||
return size;
|
||||
}
|
||||
|
||||
protected boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
protected int add(PooledConnection pc){
|
||||
if (size == slots.length){
|
||||
// grow the capacity
|
||||
setCapacity(slots.length + growBy);
|
||||
}
|
||||
int slot = nextEmptySlot();
|
||||
pc.setSlotId(slot);
|
||||
slots[slot] = pc;
|
||||
return ++size;
|
||||
}
|
||||
|
||||
protected boolean remove(PooledConnection pc) {
|
||||
|
||||
int slotId = pc.getSlotId();
|
||||
if (slots[slotId] != pc){
|
||||
PooledConnection heldBy = slots[slotId];
|
||||
logger.warn("Failed to remove from slot[{}] PooledConnection[{}] - HeldBy[{}]", pc.getSlotId(), pc, heldBy);
|
||||
return false;
|
||||
}
|
||||
slots[slotId] = null;
|
||||
--size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the load statistics from all the busy connections.
|
||||
* @param reset
|
||||
*/
|
||||
protected void collectStatistics(LoadValues values, boolean reset) {
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null){
|
||||
values.plus(slots[i].getStatistics().getValues(reset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close connections that should be considered leaked.
|
||||
*/
|
||||
protected void closeBusyConnections(long leakTimeMinutes) {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BusyConnectionBuffer.class);
|
||||
|
||||
long olderThanTime = System.currentTimeMillis() - (leakTimeMinutes*60000);
|
||||
private PooledConnection[] slots;
|
||||
|
||||
logger.debug("Closing busy connections using leakTimeMinutes {}", leakTimeMinutes);
|
||||
private final int growBy;
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null){
|
||||
//tmp.add(slots[i]);
|
||||
PooledConnection pc = slots[i];
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (pc.isLongRunning() || pc.getLastUsedTime() > olderThanTime) {
|
||||
// PooledConnection has been used recently or
|
||||
// expected to be longRunning so not closing...
|
||||
} else {
|
||||
slots[i] = null;
|
||||
--size;
|
||||
closeBusyConnection(pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void closeBusyConnection(PooledConnection pc) {
|
||||
try {
|
||||
|
||||
logger.warn("DataSourcePool closing busy connection? "+pc.getFullDescription());
|
||||
System.out.println("CLOSING busy connection: "+pc.getFullDescription());
|
||||
|
||||
pc.closeConnectionFully(false);
|
||||
private int size;
|
||||
|
||||
} catch (Exception ex) {
|
||||
// this should never actually happen
|
||||
logger.error("Error when closing potentially leaked connection "+pc.getDescription(), ex);
|
||||
}
|
||||
private int pos = -1;
|
||||
|
||||
/**
|
||||
* Create the buffer with an initial capacity and fixed growBy.
|
||||
* We generally do not want the buffer to grow very often.
|
||||
*
|
||||
* @param capacity the initial capacity
|
||||
* @param growBy the fixed amount to grow the buffer by.
|
||||
*/
|
||||
protected BusyConnectionBuffer(int capacity, int growBy) {
|
||||
this.slots = new PooledConnection[capacity];
|
||||
this.growBy = growBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information describing connections that are currently being used.
|
||||
*/
|
||||
protected String getBusyConnectionInformation(boolean toLogger) {
|
||||
|
||||
if (toLogger) {
|
||||
logger.info("Dumping [{}] busy connections: (Use datasource.xxx.capturestacktrace=true ... to get stackTraces)", size());
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null){
|
||||
PooledConnection pc = slots[i];
|
||||
if (toLogger) {
|
||||
logger.info("Busy Connection - {}", pc.getFullDescription());
|
||||
} else {
|
||||
sb.append(pc.getFullDescription()).append("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
/**
|
||||
* We can only grow (not shrink) the capacity.
|
||||
*/
|
||||
protected void setCapacity(int newCapacity) {
|
||||
if (newCapacity > slots.length) {
|
||||
PooledConnection[] current = this.slots;
|
||||
this.slots = new PooledConnection[newCapacity];
|
||||
System.arraycopy(current, 0, this.slots, 0, current.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the position of the next empty slot.
|
||||
*/
|
||||
private int nextEmptySlot() {
|
||||
}
|
||||
|
||||
// search forward
|
||||
while(++pos < slots.length) {
|
||||
if (slots[pos] == null){
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
// search from beginning
|
||||
pos = -1;
|
||||
while(++pos < slots.length) {
|
||||
if (slots[pos] == null){
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
// not expecting this
|
||||
throw new RuntimeException("No Empty Slot Found?");
|
||||
public String toString() {
|
||||
return Arrays.toString(slots);
|
||||
}
|
||||
|
||||
protected int getCapacity() {
|
||||
return slots.length;
|
||||
}
|
||||
|
||||
protected int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
protected boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
protected int add(PooledConnection pc) {
|
||||
if (size == slots.length) {
|
||||
// grow the capacity
|
||||
setCapacity(slots.length + growBy);
|
||||
}
|
||||
|
||||
int slot = nextEmptySlot();
|
||||
pc.setSlotId(slot);
|
||||
slots[slot] = pc;
|
||||
return ++size;
|
||||
}
|
||||
|
||||
protected boolean remove(PooledConnection pc) {
|
||||
|
||||
int slotId = pc.getSlotId();
|
||||
if (slots[slotId] != pc) {
|
||||
PooledConnection heldBy = slots[slotId];
|
||||
logger.warn("Failed to remove from slot[{}] PooledConnection[{}] - HeldBy[{}]", pc.getSlotId(), pc, heldBy);
|
||||
return false;
|
||||
}
|
||||
slots[slotId] = null;
|
||||
--size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the load statistics from all the busy connections.
|
||||
*
|
||||
* @param reset
|
||||
*/
|
||||
protected void collectStatistics(LoadValues values, boolean reset) {
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null) {
|
||||
values.plus(slots[i].getStatistics().getValues(reset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close connections that should be considered leaked.
|
||||
*/
|
||||
protected void closeBusyConnections(long leakTimeMinutes) {
|
||||
|
||||
long olderThanTime = System.currentTimeMillis() - (leakTimeMinutes * 60000);
|
||||
|
||||
logger.debug("Closing busy connections using leakTimeMinutes {}", leakTimeMinutes);
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null) {
|
||||
//tmp.add(slots[i]);
|
||||
PooledConnection pc = slots[i];
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (pc.isLongRunning() || pc.getLastUsedTime() > olderThanTime) {
|
||||
// PooledConnection has been used recently or
|
||||
// expected to be longRunning so not closing...
|
||||
} else {
|
||||
slots[i] = null;
|
||||
--size;
|
||||
closeBusyConnection(pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void closeBusyConnection(PooledConnection pc) {
|
||||
try {
|
||||
|
||||
logger.warn("DataSourcePool closing busy connection? " + pc.getFullDescription());
|
||||
System.out.println("CLOSING busy connection: " + pc.getFullDescription());
|
||||
|
||||
pc.closeConnectionFully(false);
|
||||
|
||||
} catch (Exception ex) {
|
||||
// this should never actually happen
|
||||
logger.error("Error when closing potentially leaked connection " + pc.getDescription(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information describing connections that are currently being used.
|
||||
*/
|
||||
protected String getBusyConnectionInformation(boolean toLogger) {
|
||||
|
||||
if (toLogger) {
|
||||
logger.info("Dumping [{}] busy connections: (Use datasource.xxx.capturestacktrace=true ... to get stackTraces)", size());
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] != null) {
|
||||
PooledConnection pc = slots[i];
|
||||
if (toLogger) {
|
||||
logger.info("Busy Connection - {}", pc.getFullDescription());
|
||||
} else {
|
||||
sb.append(pc.getFullDescription()).append("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the position of the next empty slot.
|
||||
*/
|
||||
private int nextEmptySlot() {
|
||||
|
||||
// search forward
|
||||
while (++pos < slots.length) {
|
||||
if (slots[pos] == null) {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
// search from beginning
|
||||
pos = -1;
|
||||
while (++pos < slots.length) {
|
||||
if (slots[pos] == null) {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
// not expecting this
|
||||
throw new RuntimeException("No Empty Slot Found?");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,18 +10,18 @@ package com.avaje.ebeaninternal.server.lib.sql;
|
||||
*/
|
||||
public interface DataSourceAlert {
|
||||
|
||||
/**
|
||||
* Send an alert to say the dataSource is back up.
|
||||
*/
|
||||
void dataSourceUp(String dataSourceName);
|
||||
/**
|
||||
* Send an alert to say the dataSource is back up.
|
||||
*/
|
||||
void dataSourceUp(String dataSourceName);
|
||||
|
||||
/**
|
||||
* Send an alert to say the dataSource is down.
|
||||
*/
|
||||
void dataSourceDown(String dataSourceName);
|
||||
/**
|
||||
* Send an alert to say the dataSource is down.
|
||||
*/
|
||||
void dataSourceDown(String dataSourceName);
|
||||
|
||||
/**
|
||||
* Send an alert to say the dataSource is getting close to its max size.
|
||||
*/
|
||||
void dataSourceWarning(String subject, String msg);
|
||||
/**
|
||||
* Send an alert to say the dataSource is getting close to its max size.
|
||||
*/
|
||||
void dataSourceWarning(String subject, String msg);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ import java.sql.Connection;
|
||||
* <p>
|
||||
* Example: datasource.ora10.poolListener=my.very.fancy.PoolListener
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* Notice: This listener only works if you are using the default Avaje
|
||||
* {@link DataSourcePool}.
|
||||
@@ -21,14 +21,14 @@ import java.sql.Connection;
|
||||
*/
|
||||
public interface DataSourcePoolListener {
|
||||
|
||||
/**
|
||||
* Called after a connection has been retrieved from the connection pool
|
||||
*/
|
||||
void onAfterBorrowConnection(Connection c);
|
||||
/**
|
||||
* Called after a connection has been retrieved from the connection pool
|
||||
*/
|
||||
void onAfterBorrowConnection(Connection c);
|
||||
|
||||
/**
|
||||
* Called before a connection will be put back to the connection pool
|
||||
*/
|
||||
void onBeforeReturnConnection(Connection c);
|
||||
/**
|
||||
* Called before a connection will be put back to the connection pool
|
||||
*/
|
||||
void onBeforeReturnConnection(Connection c);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ package com.avaje.ebeaninternal.server.lib.sql;
|
||||
public class DataSourcePoolStatistics {
|
||||
|
||||
private final long collectionStart;
|
||||
|
||||
|
||||
private final long count;
|
||||
|
||||
|
||||
private final long errorCount;
|
||||
|
||||
|
||||
private final long hwmMicros;
|
||||
|
||||
|
||||
private final long totalMicros;
|
||||
|
||||
/**
|
||||
|
||||
+315
-314
@@ -28,362 +28,363 @@ import java.util.Calendar;
|
||||
*/
|
||||
public class ExtendedPreparedStatement extends ExtendedStatement implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* The SQL used to create the underlying PreparedStatement.
|
||||
*/
|
||||
private final String sql;
|
||||
/**
|
||||
* The SQL used to create the underlying PreparedStatement.
|
||||
*/
|
||||
private final String sql;
|
||||
|
||||
/**
|
||||
* The key used to cache this in the connection.
|
||||
*/
|
||||
private final String cacheKey;
|
||||
/**
|
||||
* The key used to cache this in the connection.
|
||||
*/
|
||||
private final String cacheKey;
|
||||
|
||||
/**
|
||||
* Create a wrapped PreparedStatement that can be cached.
|
||||
*/
|
||||
public ExtendedPreparedStatement(PooledConnection pooledConnection, PreparedStatement pstmt, String sql, String cacheKey) {
|
||||
super(pooledConnection, pstmt);
|
||||
this.sql = sql;
|
||||
this.cacheKey = cacheKey;
|
||||
}
|
||||
|
||||
public PreparedStatement getDelegate() {
|
||||
return pstmt;
|
||||
}
|
||||
/**
|
||||
* Create a wrapped PreparedStatement that can be cached.
|
||||
*/
|
||||
public ExtendedPreparedStatement(PooledConnection pooledConnection, PreparedStatement pstmt, String sql, String cacheKey) {
|
||||
super(pooledConnection, pstmt);
|
||||
this.sql = sql;
|
||||
this.cacheKey = cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key used to cache this on the Connection.
|
||||
*/
|
||||
public String getCacheKey() {
|
||||
return cacheKey;
|
||||
}
|
||||
public PreparedStatement getDelegate() {
|
||||
return pstmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL used to create this PreparedStatement.
|
||||
*/
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
/**
|
||||
* Return the key used to cache this on the Connection.
|
||||
*/
|
||||
public String getCacheKey() {
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully close the underlying PreparedStatement. After this we can no longer
|
||||
* reuse the PreparedStatement.
|
||||
*/
|
||||
public void closeDestroy() throws SQLException {
|
||||
pstmt.close();
|
||||
}
|
||||
/**
|
||||
* Return the SQL used to create this PreparedStatement.
|
||||
*/
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PreparedStatement back into the cache. This doesn't fully
|
||||
* close the underlying PreparedStatement.
|
||||
*/
|
||||
public void close() throws SQLException {
|
||||
// return the connection back into the cache.
|
||||
pooledConnection.returnPreparedStatement(this);
|
||||
}
|
||||
/**
|
||||
* Fully close the underlying PreparedStatement. After this we can no longer
|
||||
* reuse the PreparedStatement.
|
||||
*/
|
||||
public void closeDestroy() throws SQLException {
|
||||
pstmt.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the last binding for batch execution.
|
||||
*/
|
||||
public void addBatch() throws SQLException {
|
||||
try {
|
||||
pstmt.addBatch();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check this
|
||||
// connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the PreparedStatement back into the cache. This doesn't fully
|
||||
* close the underlying PreparedStatement.
|
||||
*/
|
||||
public void close() throws SQLException {
|
||||
// return the connection back into the cache.
|
||||
pooledConnection.returnPreparedStatement(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear parameters.
|
||||
*/
|
||||
public void clearParameters() throws SQLException {
|
||||
try {
|
||||
pstmt.clearParameters();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add the last binding for batch execution.
|
||||
*/
|
||||
public void addBatch() throws SQLException {
|
||||
try {
|
||||
pstmt.addBatch();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check this
|
||||
// connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* execute the statement.
|
||||
*/
|
||||
public boolean execute() throws SQLException {
|
||||
try {
|
||||
return pstmt.execute();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clear parameters.
|
||||
*/
|
||||
public void clearParameters() throws SQLException {
|
||||
try {
|
||||
pstmt.clearParameters();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute teh query.
|
||||
*/
|
||||
public ResultSet executeQuery() throws SQLException {
|
||||
try {
|
||||
return pstmt.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* execute the statement.
|
||||
*/
|
||||
public boolean execute() throws SQLException {
|
||||
try {
|
||||
return pstmt.execute();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the dml statement.
|
||||
*/
|
||||
public int executeUpdate() throws SQLException {
|
||||
try {
|
||||
return pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute teh query.
|
||||
*/
|
||||
public ResultSet executeQuery() throws SQLException {
|
||||
try {
|
||||
return pstmt.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MetaData for the query.
|
||||
*/
|
||||
public ResultSetMetaData getMetaData() throws SQLException {
|
||||
try {
|
||||
return pstmt.getMetaData();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute the dml statement.
|
||||
*/
|
||||
public int executeUpdate() throws SQLException {
|
||||
try {
|
||||
return pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public ParameterMetaData getParameterMetaData() throws SQLException {
|
||||
return pstmt.getParameterMetaData();
|
||||
}
|
||||
/**
|
||||
* Return the MetaData for the query.
|
||||
*/
|
||||
public ResultSetMetaData getMetaData() throws SQLException {
|
||||
try {
|
||||
return pstmt.getMetaData();
|
||||
} catch (SQLException e) {
|
||||
// we got an error... need to check
|
||||
// this connection before returning it
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setArray(int i, Array x) throws SQLException {
|
||||
pstmt.setArray(i, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public ParameterMetaData getParameterMetaData() throws SQLException {
|
||||
return pstmt.getParameterMetaData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setAsciiStream(parameterIndex, x, length);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setArray(int i, Array x) throws SQLException {
|
||||
pstmt.setArray(i, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
|
||||
pstmt.setBigDecimal(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setAsciiStream(parameterIndex, x, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setBinaryStream(parameterIndex, x, length);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
|
||||
pstmt.setBigDecimal(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBlob(int i, Blob x) throws SQLException {
|
||||
pstmt.setBlob(i, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setBinaryStream(parameterIndex, x, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
|
||||
pstmt.setBoolean(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBlob(int i, Blob x) throws SQLException {
|
||||
pstmt.setBlob(i, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||
pstmt.setByte(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
|
||||
pstmt.setBoolean(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||
pstmt.setBytes(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||
pstmt.setByte(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setCharacterStream(int parameterIndex, Reader reader, int length)
|
||||
throws SQLException {
|
||||
pstmt.setCharacterStream(parameterIndex, reader, length);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||
pstmt.setBytes(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setClob(int i, Clob x) throws SQLException {
|
||||
pstmt.setClob(i, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setCharacterStream(int parameterIndex, Reader reader, int length)
|
||||
throws SQLException {
|
||||
pstmt.setCharacterStream(parameterIndex, reader, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDate(int parameterIndex, Date x) throws SQLException {
|
||||
pstmt.setDate(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setClob(int i, Clob x) throws SQLException {
|
||||
pstmt.setClob(i, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
|
||||
pstmt.setDate(parameterIndex, x, cal);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDate(int parameterIndex, Date x) throws SQLException {
|
||||
pstmt.setDate(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDouble(int parameterIndex, double x) throws SQLException {
|
||||
pstmt.setDouble(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
|
||||
pstmt.setDate(parameterIndex, x, cal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setFloat(int parameterIndex, float x) throws SQLException {
|
||||
pstmt.setFloat(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setDouble(int parameterIndex, double x) throws SQLException {
|
||||
pstmt.setDouble(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setInt(int parameterIndex, int x) throws SQLException {
|
||||
pstmt.setInt(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setFloat(int parameterIndex, float x) throws SQLException {
|
||||
pstmt.setFloat(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setLong(int parameterIndex, long x) throws SQLException {
|
||||
pstmt.setLong(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setInt(int parameterIndex, int x) throws SQLException {
|
||||
pstmt.setInt(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
||||
pstmt.setNull(parameterIndex, sqlType);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setLong(int parameterIndex, long x) throws SQLException {
|
||||
pstmt.setLong(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
|
||||
pstmt.setNull(paramIndex, sqlType, typeName);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
||||
pstmt.setNull(parameterIndex, sqlType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
|
||||
pstmt.setNull(paramIndex, sqlType, typeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x, targetSqlType);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
|
||||
throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x, targetSqlType, scale);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x, targetSqlType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setRef(int i, Ref x) throws SQLException {
|
||||
pstmt.setRef(i, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
|
||||
throws SQLException {
|
||||
pstmt.setObject(parameterIndex, x, targetSqlType, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setShort(int parameterIndex, short x) throws SQLException {
|
||||
pstmt.setShort(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setRef(int i, Ref x) throws SQLException {
|
||||
pstmt.setRef(i, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setString(int parameterIndex, String x) throws SQLException {
|
||||
pstmt.setString(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setShort(int parameterIndex, short x) throws SQLException {
|
||||
pstmt.setShort(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTime(int parameterIndex, Time x) throws SQLException {
|
||||
pstmt.setTime(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setString(int parameterIndex, String x) throws SQLException {
|
||||
pstmt.setString(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
|
||||
pstmt.setTime(parameterIndex, x, cal);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTime(int parameterIndex, Time x) throws SQLException {
|
||||
pstmt.setTime(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
|
||||
pstmt.setTimestamp(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
|
||||
pstmt.setTime(parameterIndex, x, cal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
|
||||
pstmt.setTimestamp(parameterIndex, x, cal);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
|
||||
pstmt.setTimestamp(parameterIndex, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
* @deprecated
|
||||
*/
|
||||
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setUnicodeStream(parameterIndex, x, length);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
|
||||
pstmt.setTimestamp(parameterIndex, x, cal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setURL(int parameterIndex, URL x) throws SQLException {
|
||||
pstmt.setURL(parameterIndex, x);
|
||||
}
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
||||
pstmt.setUnicodeStream(parameterIndex, x, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard PreparedStatement method execution.
|
||||
*/
|
||||
public void setURL(int parameterIndex, URL x) throws SQLException {
|
||||
pstmt.setURL(parameterIndex, x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,313 +16,312 @@ import com.avaje.ebeaninternal.jdbc.PreparedStatementDelegator;
|
||||
* for the case where someone uses the Statement api on an ExtendedPreparedStatement.
|
||||
* </p>
|
||||
*/
|
||||
public abstract class ExtendedStatement extends PreparedStatementDelegator
|
||||
{
|
||||
public abstract class ExtendedStatement extends PreparedStatementDelegator {
|
||||
|
||||
/**
|
||||
* The pooled connection this Statement belongs to.
|
||||
*/
|
||||
protected final PooledConnection pooledConnection;
|
||||
/**
|
||||
* The pooled connection this Statement belongs to.
|
||||
*/
|
||||
protected final PooledConnection pooledConnection;
|
||||
|
||||
/**
|
||||
* The underlying Statement that this object wraps.
|
||||
*/
|
||||
protected final PreparedStatement pstmt;
|
||||
/**
|
||||
* The underlying Statement that this object wraps.
|
||||
*/
|
||||
protected final PreparedStatement pstmt;
|
||||
|
||||
/**
|
||||
* Create the ExtendedStatement for a given pooledConnection.
|
||||
*/
|
||||
public ExtendedStatement(PooledConnection pooledConnection, PreparedStatement pstmt) {
|
||||
super(pstmt);
|
||||
/**
|
||||
* Create the ExtendedStatement for a given pooledConnection.
|
||||
*/
|
||||
public ExtendedStatement(PooledConnection pooledConnection, PreparedStatement pstmt) {
|
||||
super(pstmt);
|
||||
|
||||
this.pooledConnection = pooledConnection;
|
||||
this.pstmt = pstmt;
|
||||
}
|
||||
this.pooledConnection = pooledConnection;
|
||||
this.pstmt = pstmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the statement back into the statement cache.
|
||||
*/
|
||||
public abstract void close() throws SQLException;
|
||||
/**
|
||||
* Put the statement back into the statement cache.
|
||||
*/
|
||||
public abstract void close() throws SQLException;
|
||||
|
||||
/**
|
||||
* Return the underlying connection.
|
||||
*/
|
||||
public Connection getConnection() throws SQLException {
|
||||
try {
|
||||
return pstmt.getConnection();
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the underlying connection.
|
||||
*/
|
||||
public Connection getConnection() throws SQLException {
|
||||
try {
|
||||
return pstmt.getConnection();
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the sql for batch execution.
|
||||
*/
|
||||
public void addBatch(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
pstmt.addBatch(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add the sql for batch execution.
|
||||
*/
|
||||
public void addBatch(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
pstmt.addBatch(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the sql.
|
||||
*/
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.execute(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute the sql.
|
||||
*/
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.execute(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query.
|
||||
*/
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.executeQuery(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute the query.
|
||||
*/
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.executeQuery(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the dml sql.
|
||||
*/
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute the dml sql.
|
||||
*/
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
try {
|
||||
pooledConnection.setLastStatement(sql);
|
||||
return pstmt.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
pooledConnection.addError(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int[] executeBatch() throws SQLException {
|
||||
return pstmt.executeBatch();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int[] executeBatch() throws SQLException {
|
||||
return pstmt.executeBatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void cancel() throws SQLException {
|
||||
pstmt.cancel();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void cancel() throws SQLException {
|
||||
pstmt.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void clearBatch() throws SQLException {
|
||||
pstmt.clearBatch();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void clearBatch() throws SQLException {
|
||||
pstmt.clearBatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void clearWarnings() throws SQLException {
|
||||
pstmt.clearWarnings();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void clearWarnings() throws SQLException {
|
||||
pstmt.clearWarnings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return pstmt.getFetchDirection();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return pstmt.getFetchDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getFetchSize() throws SQLException {
|
||||
return pstmt.getFetchSize();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getFetchSize() throws SQLException {
|
||||
return pstmt.getFetchSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getMaxFieldSize() throws SQLException {
|
||||
return pstmt.getMaxFieldSize();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getMaxFieldSize() throws SQLException {
|
||||
return pstmt.getMaxFieldSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getMaxRows() throws SQLException {
|
||||
return pstmt.getMaxRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean getMoreResults() throws SQLException {
|
||||
return pstmt.getMoreResults();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getMaxRows() throws SQLException {
|
||||
return pstmt.getMaxRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getQueryTimeout() throws SQLException {
|
||||
return pstmt.getQueryTimeout();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean getMoreResults() throws SQLException {
|
||||
return pstmt.getMoreResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
return pstmt.getResultSet();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getQueryTimeout() throws SQLException {
|
||||
return pstmt.getQueryTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return pstmt.getResultSetConcurrency();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetType() throws SQLException {
|
||||
return pstmt.getResultSetType();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
return pstmt.getResultSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getUpdateCount() throws SQLException {
|
||||
return pstmt.getUpdateCount();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return pstmt.getResultSetConcurrency();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return pstmt.getWarnings();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetType() throws SQLException {
|
||||
return pstmt.getResultSetType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setCursorName(String name) throws SQLException {
|
||||
pstmt.setCursorName(name);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getUpdateCount() throws SQLException {
|
||||
return pstmt.getUpdateCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
pstmt.setEscapeProcessing(enable);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return pstmt.getWarnings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
pstmt.setFetchDirection(direction);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setCursorName(String name) throws SQLException {
|
||||
pstmt.setCursorName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
pstmt.setFetchSize(rows);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
pstmt.setEscapeProcessing(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setMaxFieldSize(int max) throws SQLException {
|
||||
pstmt.setMaxFieldSize(max);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
pstmt.setFetchDirection(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
pstmt.setMaxRows(max);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
pstmt.setFetchSize(rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setQueryTimeout(int seconds) throws SQLException {
|
||||
pstmt.setQueryTimeout(seconds);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setMaxFieldSize(int max) throws SQLException {
|
||||
pstmt.setMaxFieldSize(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean getMoreResults(int i) throws SQLException {
|
||||
return pstmt.getMoreResults(i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
pstmt.setMaxRows(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return pstmt.getGeneratedKeys();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public void setQueryTimeout(int seconds) throws SQLException {
|
||||
pstmt.setQueryTimeout(seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, int i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean getMoreResults(int i) throws SQLException {
|
||||
return pstmt.getMoreResults(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, int[] i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return pstmt.getGeneratedKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, String[] i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, int i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, int i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, int[] i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, int[] i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int executeUpdate(String s, String[] i) throws SQLException {
|
||||
return pstmt.executeUpdate(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, String[] i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, int i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return pstmt.getResultSetHoldability();
|
||||
}
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, int[] i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public boolean execute(String s, String[] i) throws SQLException {
|
||||
return pstmt.execute(s, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Statement method call.
|
||||
*/
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return pstmt.getResultSetHoldability();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadVal
|
||||
class FreeConnectionBuffer {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FreeConnectionBuffer.class);
|
||||
|
||||
|
||||
/**
|
||||
* Buffer oriented for add and remove.
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ class FreeConnectionBuffer {
|
||||
|
||||
// create a temporary list
|
||||
List<PooledConnection> tempList = new ArrayList<PooledConnection>(freeBuffer.size());
|
||||
|
||||
|
||||
// add all the connections into it
|
||||
for (PooledConnection c : freeBuffer) {
|
||||
tempList.add(c);
|
||||
@@ -65,15 +65,15 @@ class FreeConnectionBuffer {
|
||||
|
||||
// clear the buffer (in case it takes some time to close these connections).
|
||||
freeBuffer.clear();
|
||||
|
||||
|
||||
logger.debug("... closing all {} connections from the free list with logErrors: {}", tempList.size(), logErrors);
|
||||
for (int i = 0; i < tempList.size(); i++) {
|
||||
PooledConnection pooledConnection = tempList.get(i);
|
||||
logger.debug("... closing {} of {} connections from the free list", i, tempList.size());
|
||||
logger.debug("... closing {} of {} connections from the free list", i, tempList.size());
|
||||
pooledConnection.closeConnectionFully(logErrors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trim any inactive connections that have not been used since usedSince.
|
||||
*/
|
||||
|
||||
@@ -13,520 +13,520 @@ import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadVal
|
||||
|
||||
public class PooledConnectionQueue {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PooledConnectionQueue.class);
|
||||
|
||||
private static final TimeUnit MILLIS_TIME_UNIT = TimeUnit.MILLISECONDS;
|
||||
private static final Logger logger = LoggerFactory.getLogger(PooledConnectionQueue.class);
|
||||
|
||||
private final String name;
|
||||
|
||||
private final DataSourcePool pool;
|
||||
|
||||
/**
|
||||
* A 'circular' buffer designed specifically for free connections.
|
||||
*/
|
||||
private final FreeConnectionBuffer freeList;
|
||||
|
||||
/**
|
||||
* A 'slots' buffer designed specifically for busy connections.
|
||||
* Fast add remove based on slot id.
|
||||
*/
|
||||
private final BusyConnectionBuffer busyList;
|
||||
private static final TimeUnit MILLIS_TIME_UNIT = TimeUnit.MILLISECONDS;
|
||||
|
||||
/**
|
||||
* Load statistics collected off connections that have closed fully (left the pool).
|
||||
*/
|
||||
private final PooledConnectionStatistics collectedStats = new PooledConnectionStatistics();
|
||||
|
||||
/**
|
||||
* Currently accumulated load statistics.
|
||||
*/
|
||||
private LoadValues accumulatedValues = new LoadValues();
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Main lock guarding all access
|
||||
*/
|
||||
private final ReentrantLock lock;
|
||||
|
||||
/**
|
||||
* Condition for threads waiting to take a connection
|
||||
*/
|
||||
private final Condition notEmpty;
|
||||
private final DataSourcePool pool;
|
||||
|
||||
private int connectionId;
|
||||
/**
|
||||
* A 'circular' buffer designed specifically for free connections.
|
||||
*/
|
||||
private final FreeConnectionBuffer freeList;
|
||||
|
||||
private final long waitTimeoutMillis;
|
||||
|
||||
private final long leakTimeMinutes;
|
||||
|
||||
private final long maxAgeMillis;
|
||||
/**
|
||||
* A 'slots' buffer designed specifically for busy connections.
|
||||
* Fast add remove based on slot id.
|
||||
*/
|
||||
private final BusyConnectionBuffer busyList;
|
||||
|
||||
private int warningSize;
|
||||
|
||||
private int maxSize;
|
||||
|
||||
private int minSize;
|
||||
|
||||
/**
|
||||
* Number of threads in the wait queue.
|
||||
*/
|
||||
private int waitingThreads;
|
||||
|
||||
/**
|
||||
* Number of times a thread had to wait.
|
||||
*/
|
||||
private int waitCount;
|
||||
|
||||
/**
|
||||
* Number of times a connection was got from this queue.
|
||||
*/
|
||||
private int hitCount;
|
||||
|
||||
/**
|
||||
* The high water mark for the queue size.
|
||||
*/
|
||||
private int highWaterMark;
|
||||
|
||||
/**
|
||||
* Last time the pool was reset. Used to close busy connections as they are
|
||||
* returned to the pool that where created prior to the lastResetTime.
|
||||
*/
|
||||
private long lastResetTime;
|
||||
/**
|
||||
* Load statistics collected off connections that have closed fully (left the pool).
|
||||
*/
|
||||
private final PooledConnectionStatistics collectedStats = new PooledConnectionStatistics();
|
||||
|
||||
private boolean doingShutdown;
|
||||
/**
|
||||
* Currently accumulated load statistics.
|
||||
*/
|
||||
private LoadValues accumulatedValues = new LoadValues();
|
||||
|
||||
public PooledConnectionQueue(DataSourcePool pool) {
|
||||
|
||||
this.pool = pool;
|
||||
this.name = pool.getName();
|
||||
this.minSize = pool.getMinSize();
|
||||
this.maxSize = pool.getMaxSize();
|
||||
|
||||
this.warningSize = pool.getWarningSize();
|
||||
this.waitTimeoutMillis = pool.getWaitTimeoutMillis();
|
||||
this.leakTimeMinutes = pool.getLeakTimeMinutes();
|
||||
this.maxAgeMillis = pool.getMaxAgeMillis();
|
||||
/**
|
||||
* Main lock guarding all access
|
||||
*/
|
||||
private final ReentrantLock lock;
|
||||
|
||||
this.busyList = new BusyConnectionBuffer(maxSize, 20);
|
||||
this.freeList = new FreeConnectionBuffer();
|
||||
/**
|
||||
* Condition for threads waiting to take a connection
|
||||
*/
|
||||
private final Condition notEmpty;
|
||||
|
||||
this.lock = new ReentrantLock(false);
|
||||
this.notEmpty = lock.newCondition();
|
||||
}
|
||||
|
||||
private Status createStatus() {
|
||||
return new Status(name, minSize, maxSize, freeList.size(), busyList.size(), waitingThreads, highWaterMark, waitCount, hitCount);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
return createStatus().toString();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect statistics of a connection that is fully closing
|
||||
*/
|
||||
protected void reportClosingConnection(PooledConnection pooledConnection) {
|
||||
|
||||
collectedStats.add(pooledConnection.getStatistics());
|
||||
}
|
||||
private int connectionId;
|
||||
|
||||
public DataSourcePoolStatistics getStatistics(boolean reset) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
private final long waitTimeoutMillis;
|
||||
|
||||
LoadValues aggregate = collectedStats.getValues(reset);
|
||||
private final long leakTimeMinutes;
|
||||
|
||||
freeList.collectStatistics(aggregate, reset);
|
||||
busyList.collectStatistics(aggregate, reset);
|
||||
private final long maxAgeMillis;
|
||||
|
||||
aggregate.plus(accumulatedValues);
|
||||
|
||||
this.accumulatedValues = (reset) ? new LoadValues() : aggregate;
|
||||
|
||||
return new DataSourcePoolStatistics(aggregate.getCollectionStart(), aggregate.getCount(), aggregate.getErrorCount(), aggregate.getHwmMicros(), aggregate.getTotalMicros());
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
private int warningSize;
|
||||
|
||||
private int maxSize;
|
||||
|
||||
private int minSize;
|
||||
|
||||
/**
|
||||
* Number of threads in the wait queue.
|
||||
*/
|
||||
private int waitingThreads;
|
||||
|
||||
/**
|
||||
* Number of times a thread had to wait.
|
||||
*/
|
||||
private int waitCount;
|
||||
|
||||
/**
|
||||
* Number of times a connection was got from this queue.
|
||||
*/
|
||||
private int hitCount;
|
||||
|
||||
/**
|
||||
* The high water mark for the queue size.
|
||||
*/
|
||||
private int highWaterMark;
|
||||
|
||||
/**
|
||||
* Last time the pool was reset. Used to close busy connections as they are
|
||||
* returned to the pool that where created prior to the lastResetTime.
|
||||
*/
|
||||
private long lastResetTime;
|
||||
|
||||
private boolean doingShutdown;
|
||||
|
||||
public PooledConnectionQueue(DataSourcePool pool) {
|
||||
|
||||
this.pool = pool;
|
||||
this.name = pool.getName();
|
||||
this.minSize = pool.getMinSize();
|
||||
this.maxSize = pool.getMaxSize();
|
||||
|
||||
this.warningSize = pool.getWarningSize();
|
||||
this.waitTimeoutMillis = pool.getWaitTimeoutMillis();
|
||||
this.leakTimeMinutes = pool.getLeakTimeMinutes();
|
||||
this.maxAgeMillis = pool.getMaxAgeMillis();
|
||||
|
||||
this.busyList = new BusyConnectionBuffer(maxSize, 20);
|
||||
this.freeList = new FreeConnectionBuffer();
|
||||
|
||||
this.lock = new ReentrantLock(false);
|
||||
this.notEmpty = lock.newCondition();
|
||||
}
|
||||
|
||||
public Status getStatus(boolean reset) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
|
||||
private Status createStatus() {
|
||||
return new Status(name, minSize, maxSize, freeList.size(), busyList.size(), waitingThreads, highWaterMark, waitCount, hitCount);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
return createStatus().toString();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect statistics of a connection that is fully closing
|
||||
*/
|
||||
protected void reportClosingConnection(PooledConnection pooledConnection) {
|
||||
|
||||
collectedStats.add(pooledConnection.getStatistics());
|
||||
}
|
||||
|
||||
public DataSourcePoolStatistics getStatistics(boolean reset) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
|
||||
LoadValues aggregate = collectedStats.getValues(reset);
|
||||
|
||||
freeList.collectStatistics(aggregate, reset);
|
||||
busyList.collectStatistics(aggregate, reset);
|
||||
|
||||
aggregate.plus(accumulatedValues);
|
||||
|
||||
this.accumulatedValues = (reset) ? new LoadValues() : aggregate;
|
||||
|
||||
return new DataSourcePoolStatistics(aggregate.getCollectionStart(), aggregate.getCount(), aggregate.getErrorCount(), aggregate.getHwmMicros(), aggregate.getTotalMicros());
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Status getStatus(boolean reset) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
Status s = createStatus();
|
||||
if (reset) {
|
||||
highWaterMark = busyList.size();
|
||||
hitCount = 0;
|
||||
waitCount = 0;
|
||||
}
|
||||
return s;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMinSize(int minSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (minSize > this.maxSize) {
|
||||
throw new IllegalArgumentException("minSize " + minSize + " > maxSize " + this.maxSize);
|
||||
}
|
||||
this.minSize = minSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMaxSize(int maxSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (maxSize < this.minSize) {
|
||||
throw new IllegalArgumentException("maxSize " + maxSize + " < minSize " + this.minSize);
|
||||
}
|
||||
this.busyList.setCapacity(maxSize);
|
||||
this.maxSize = maxSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWarningSize(int warningSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (warningSize > this.maxSize) {
|
||||
throw new IllegalArgumentException("warningSize " + warningSize + " > maxSize " + this.maxSize);
|
||||
}
|
||||
this.warningSize = warningSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private int totalConnections() {
|
||||
return freeList.size() + busyList.size();
|
||||
}
|
||||
|
||||
public void ensureMinimumConnections() throws SQLException {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
int add = minSize - totalConnections();
|
||||
if (add > 0) {
|
||||
for (int i = 0; i < add; i++) {
|
||||
PooledConnection c = pool.createConnectionForQueue(connectionId++);
|
||||
freeList.add(c);
|
||||
}
|
||||
notEmpty.signal();
|
||||
}
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a PooledConnection.
|
||||
*/
|
||||
protected void returnPooledConnection(PooledConnection c, boolean forceClose) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (!busyList.remove(c)) {
|
||||
logger.error("Connection [{}] not found in BusyList? ", c);
|
||||
}
|
||||
if (forceClose || c.shouldTrimOnReturn(lastResetTime, maxAgeMillis)) {
|
||||
c.closeConnectionFully(false);
|
||||
|
||||
} else {
|
||||
freeList.add(c);
|
||||
notEmpty.signal();
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private PooledConnection extractFromFreeList() {
|
||||
PooledConnection c = freeList.remove();
|
||||
registerBusyConnection(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public PooledConnection getPooledConnection() throws SQLException {
|
||||
|
||||
try {
|
||||
PooledConnection pc = _getPooledConnection();
|
||||
pc.resetForUse();
|
||||
return pc;
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
String msg = "Interrupted getting connection from pool " + e;
|
||||
throw new SQLException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the PooledConnection with the busyList.
|
||||
*/
|
||||
private int registerBusyConnection(PooledConnection c) {
|
||||
int busySize = busyList.add(c);
|
||||
if (busySize > highWaterMark) {
|
||||
highWaterMark = busySize;
|
||||
}
|
||||
return busySize;
|
||||
}
|
||||
|
||||
private PooledConnection _getPooledConnection() throws InterruptedException, SQLException {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lockInterruptibly();
|
||||
try {
|
||||
if (doingShutdown) {
|
||||
throw new SQLException("Trying to access the Connection Pool when it is shutting down");
|
||||
}
|
||||
|
||||
// this includes attempts that fail with InterruptedException
|
||||
// or SQLException but that is ok as its only an indicator
|
||||
hitCount++;
|
||||
|
||||
// are other threads already waiting? (they get priority)
|
||||
if (waitingThreads == 0) {
|
||||
|
||||
if (!freeList.isEmpty()) {
|
||||
// we have a free connection to return
|
||||
return extractFromFreeList();
|
||||
}
|
||||
|
||||
if (busyList.size() < maxSize) {
|
||||
// grow the connection pool
|
||||
PooledConnection c = pool.createConnectionForQueue(connectionId++);
|
||||
int busySize = registerBusyConnection(c);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("DataSourcePool [{}] grow; id[{}] busy[{}] max[{}]", name, c.getName(), busySize, maxSize);
|
||||
}
|
||||
checkForWarningSize();
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// The pool is at maximum size. We are going to go into
|
||||
// a wait loop until connections are returned into the pool.
|
||||
waitCount++;
|
||||
waitingThreads++;
|
||||
return _getPooledConnectionWaitLoop();
|
||||
} finally {
|
||||
waitingThreads--;
|
||||
}
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Got into a loop waiting for connections to be returned to the pool.
|
||||
*/
|
||||
private PooledConnection _getPooledConnectionWaitLoop() throws SQLException, InterruptedException {
|
||||
|
||||
long nanos = MILLIS_TIME_UNIT.toNanos(waitTimeoutMillis);
|
||||
for (; ; ) {
|
||||
|
||||
if (nanos <= 0) {
|
||||
String msg = "Unsuccessfully waited [" + waitTimeoutMillis + "] millis for a connection to be returned."
|
||||
+ " No connections are free. You need to Increase the max connections of [" + maxSize + "]"
|
||||
+ " or look for a connection pool leak using datasource.xxx.capturestacktrace=true";
|
||||
if (pool.isCaptureStackTrace()) {
|
||||
dumpBusyConnectionInformation();
|
||||
}
|
||||
|
||||
throw new SQLException(msg);
|
||||
}
|
||||
|
||||
try {
|
||||
nanos = notEmpty.awaitNanos(nanos);
|
||||
if (!freeList.isEmpty()) {
|
||||
// successfully waited
|
||||
return extractFromFreeList();
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
notEmpty.signal(); // propagate to non-interrupted thread
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
doingShutdown = true;
|
||||
Status status = createStatus();
|
||||
DataSourcePoolStatistics statistics = pool.getStatistics(false);
|
||||
logger.debug("DataSourcePool [{}] shutdown {} - Statistics {}", name, status, statistics);
|
||||
|
||||
closeFreeConnections(true);
|
||||
|
||||
if (!busyList.isEmpty()) {
|
||||
logger.warn("Closing busy connections on shutdown size: " + busyList.size());
|
||||
dumpBusyConnectionInformation();
|
||||
closeBusyConnections(0);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all the connections in the pool and any current busy connections
|
||||
* when they are returned. New connections will be then created on demand.
|
||||
* <p>
|
||||
* This is typically done when a database down event occurs.
|
||||
* </p>
|
||||
*/
|
||||
public void reset(long leakTimeMinutes) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
Status status = createStatus();
|
||||
logger.info("Reseting DataSourcePool [{}] {}", name, status);
|
||||
lastResetTime = System.currentTimeMillis();
|
||||
|
||||
closeFreeConnections(false);
|
||||
closeBusyConnections(leakTimeMinutes);
|
||||
|
||||
logger.info("Busy Connections:\n" + getBusyConnectionInformation());
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void trim(long maxInactiveMillis, long maxAgeMillis) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (trimInactiveConnections(maxInactiveMillis, maxAgeMillis) > 0) {
|
||||
try {
|
||||
Status s = createStatus();
|
||||
if (reset){
|
||||
highWaterMark = busyList.size();
|
||||
hitCount = 0;
|
||||
waitCount = 0;
|
||||
}
|
||||
return s;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMinSize(int minSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (minSize > this.maxSize){
|
||||
throw new IllegalArgumentException("minSize "+minSize+" > maxSize "+this.maxSize);
|
||||
}
|
||||
this.minSize = minSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMaxSize(int maxSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (maxSize < this.minSize){
|
||||
throw new IllegalArgumentException("maxSize "+maxSize+" < minSize "+this.minSize);
|
||||
}
|
||||
this.busyList.setCapacity(maxSize);
|
||||
this.maxSize = maxSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWarningSize(int warningSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (warningSize > this.maxSize){
|
||||
throw new IllegalArgumentException("warningSize "+warningSize+" > maxSize "+this.maxSize);
|
||||
}
|
||||
this.warningSize = warningSize;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private int totalConnections() {
|
||||
return freeList.size() + busyList.size();
|
||||
}
|
||||
|
||||
public void ensureMinimumConnections() throws SQLException {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
int add = minSize - totalConnections();
|
||||
if (add > 0){
|
||||
for (int i = 0; i < add; i++) {
|
||||
PooledConnection c = pool.createConnectionForQueue(connectionId++);
|
||||
freeList.add(c);
|
||||
}
|
||||
notEmpty.signal();
|
||||
}
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a PooledConnection.
|
||||
*/
|
||||
protected void returnPooledConnection(PooledConnection c, boolean forceClose) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (!busyList.remove(c)) {
|
||||
logger.error("Connection [{}] not found in BusyList? ", c);
|
||||
}
|
||||
if (forceClose || c.shouldTrimOnReturn(lastResetTime, maxAgeMillis)) {
|
||||
c.closeConnectionFully(false);
|
||||
|
||||
} else {
|
||||
freeList.add(c);
|
||||
notEmpty.signal();
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
ensureMinimumConnections();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error trying to ensure minimum connections", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private PooledConnection extractFromFreeList() {
|
||||
PooledConnection c = freeList.remove();
|
||||
registerBusyConnection(c);
|
||||
return c;
|
||||
}
|
||||
/**
|
||||
* Trim connections that have been not used for some time.
|
||||
*/
|
||||
private int trimInactiveConnections(long maxInactiveMillis, long maxAgeMillis) {
|
||||
|
||||
public PooledConnection getPooledConnection() throws SQLException {
|
||||
|
||||
try {
|
||||
PooledConnection pc = _getPooledConnection();
|
||||
pc.resetForUse();
|
||||
return pc;
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
String msg = "Interrupted getting connection from pool "+e;
|
||||
throw new SQLException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the PooledConnection with the busyList.
|
||||
*/
|
||||
private int registerBusyConnection(PooledConnection c) {
|
||||
int busySize = busyList.add(c);
|
||||
if (busySize > highWaterMark){
|
||||
highWaterMark = busySize;
|
||||
}
|
||||
return busySize;
|
||||
}
|
||||
|
||||
private PooledConnection _getPooledConnection() throws InterruptedException, SQLException {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lockInterruptibly();
|
||||
try {
|
||||
if (doingShutdown) {
|
||||
throw new SQLException("Trying to access the Connection Pool when it is shutting down");
|
||||
}
|
||||
|
||||
// this includes attempts that fail with InterruptedException
|
||||
// or SQLException but that is ok as its only an indicator
|
||||
hitCount++;
|
||||
|
||||
// are other threads already waiting? (they get priority)
|
||||
if (waitingThreads == 0){
|
||||
|
||||
if (!freeList.isEmpty()){
|
||||
// we have a free connection to return
|
||||
return extractFromFreeList();
|
||||
}
|
||||
|
||||
if (busyList.size() < maxSize){
|
||||
// grow the connection pool
|
||||
PooledConnection c = pool.createConnectionForQueue(connectionId++);
|
||||
int busySize = registerBusyConnection(c);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("DataSourcePool [{}] grow; id[{}] busy[{}] max[{}]", name, c.getName(), busySize, maxSize);
|
||||
}
|
||||
checkForWarningSize();
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// The pool is at maximum size. We are going to go into
|
||||
// a wait loop until connections are returned into the pool.
|
||||
waitCount++;
|
||||
waitingThreads++;
|
||||
return _getPooledConnectionWaitLoop();
|
||||
} finally {
|
||||
waitingThreads--;
|
||||
}
|
||||
long usedSince = System.currentTimeMillis() - maxInactiveMillis;
|
||||
long createdSince = (maxAgeMillis == 0) ? 0 : System.currentTimeMillis() - maxAgeMillis;
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
int trimedCount = freeList.trim(usedSince, createdSince);
|
||||
if (trimedCount > 0) {
|
||||
logger.debug("DataSourcePool [{}] trimmed [{}] inactive connections. New size[{}]", name, trimedCount, totalConnections());
|
||||
}
|
||||
|
||||
/**
|
||||
* Got into a loop waiting for connections to be returned to the pool.
|
||||
*/
|
||||
private PooledConnection _getPooledConnectionWaitLoop() throws SQLException, InterruptedException {
|
||||
return trimedCount;
|
||||
}
|
||||
|
||||
long nanos = MILLIS_TIME_UNIT.toNanos(waitTimeoutMillis);
|
||||
for (;;) {
|
||||
|
||||
if (nanos <= 0) {
|
||||
String msg = "Unsuccessfully waited ["+waitTimeoutMillis+"] millis for a connection to be returned."
|
||||
+ " No connections are free. You need to Increase the max connections of ["+maxSize+"]"
|
||||
+ " or look for a connection pool leak using datasource.xxx.capturestacktrace=true";
|
||||
if (pool.isCaptureStackTrace()) {
|
||||
dumpBusyConnectionInformation();
|
||||
}
|
||||
|
||||
throw new SQLException(msg);
|
||||
}
|
||||
|
||||
try {
|
||||
nanos = notEmpty.awaitNanos(nanos);
|
||||
if (!freeList.isEmpty()) {
|
||||
// successfully waited
|
||||
return extractFromFreeList();
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
notEmpty.signal(); // propagate to non-interrupted thread
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Close all the connections that are in the free list.
|
||||
*/
|
||||
public void closeFreeConnections(boolean logErrors) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
freeList.closeAll(logErrors);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
doingShutdown = true;
|
||||
Status status = createStatus();
|
||||
DataSourcePoolStatistics statistics = pool.getStatistics(false);
|
||||
logger.debug("DataSourcePool [{}] shutdown {} - Statistics {}", name, status, statistics);
|
||||
|
||||
closeFreeConnections(true);
|
||||
|
||||
if (!busyList.isEmpty()) {
|
||||
logger.warn("Closing busy connections on shutdown size: "+ busyList.size());
|
||||
dumpBusyConnectionInformation();
|
||||
closeBusyConnections(0);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close any busy connections that have not been used for some time.
|
||||
* <p>
|
||||
* These connections are considered to have leaked from the connection pool.
|
||||
* </p>
|
||||
* <p>
|
||||
* Connection leaks occur when code doesn't ensure that connections are
|
||||
* closed() after they have been finished with. There should be an
|
||||
* appropriate try catch finally block to ensure connections are always
|
||||
* closed and put back into the pool.
|
||||
* </p>
|
||||
*/
|
||||
public void closeBusyConnections(long leakTimeMinutes) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
busyList.closeBusyConnections(leakTimeMinutes);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all the connections in the pool and any current busy connections
|
||||
* when they are returned. New connections will be then created on demand.
|
||||
* <p>
|
||||
* This is typically done when a database down event occurs.
|
||||
* </p>
|
||||
*/
|
||||
public void reset(long leakTimeMinutes) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
Status status = createStatus();
|
||||
logger.info("Reseting DataSourcePool [{}] {}", name, status);
|
||||
lastResetTime = System.currentTimeMillis();
|
||||
/**
|
||||
* As the pool grows it gets closer to the maxConnections limit. We can send
|
||||
* an Alert (or warning) as we get close to this limit and hence an
|
||||
* Administrator could increase the pool size if desired.
|
||||
* <p>
|
||||
* This is called whenever the pool grows in size (towards the max limit).
|
||||
* </p>
|
||||
*/
|
||||
private void checkForWarningSize() {
|
||||
|
||||
closeFreeConnections(false);
|
||||
closeBusyConnections(leakTimeMinutes);
|
||||
// the the total number of connections that we can add
|
||||
// to the pool before it hits the maximum
|
||||
int availableGrowth = (maxSize - totalConnections());
|
||||
|
||||
logger.info("Busy Connections:\n" + getBusyConnectionInformation());
|
||||
if (availableGrowth < warningSize) {
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
closeBusyConnections(leakTimeMinutes);
|
||||
|
||||
String msg = "DataSourcePool [" + name + "] is [" + availableGrowth + "] connections from its maximum size.";
|
||||
pool.notifyWarning(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void trim(long maxInactiveMillis, long maxAgeMillis) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
if (trimInactiveConnections(maxInactiveMillis, maxAgeMillis) > 0) {
|
||||
try {
|
||||
ensureMinimumConnections();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error trying to ensure minimum connections", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim connections that have been not used for some time.
|
||||
*/
|
||||
private int trimInactiveConnections(long maxInactiveMillis, long maxAgeMillis) {
|
||||
|
||||
long usedSince = System.currentTimeMillis() - maxInactiveMillis;
|
||||
long createdSince = (maxAgeMillis == 0) ? 0 : System.currentTimeMillis() - maxAgeMillis;
|
||||
|
||||
int trimedCount = freeList.trim(usedSince, createdSince);
|
||||
if (trimedCount > 0) {
|
||||
logger.debug("DataSourcePool [{}] trimmed [{}] inactive connections. New size[{}]", name, trimedCount, totalConnections());
|
||||
}
|
||||
return trimedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all the connections that are in the free list.
|
||||
*/
|
||||
public void closeFreeConnections(boolean logErrors) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
freeList.closeAll(logErrors);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close any busy connections that have not been used for some time.
|
||||
* <p>
|
||||
* These connections are considered to have leaked from the connection pool.
|
||||
* </p>
|
||||
* <p>
|
||||
* Connection leaks occur when code doesn't ensure that connections are
|
||||
* closed() after they have been finished with. There should be an
|
||||
* appropriate try catch finally block to ensure connections are always
|
||||
* closed and put back into the pool.
|
||||
* </p>
|
||||
*/
|
||||
public void closeBusyConnections(long leakTimeMinutes) {
|
||||
public String getBusyConnectionInformation() {
|
||||
return getBusyConnectionInformation(false);
|
||||
}
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
busyList.closeBusyConnections(leakTimeMinutes);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* As the pool grows it gets closer to the maxConnections limit. We can send
|
||||
* an Alert (or warning) as we get close to this limit and hence an
|
||||
* Administrator could increase the pool size if desired.
|
||||
* <p>
|
||||
* This is called whenever the pool grows in size (towards the max limit).
|
||||
* </p>
|
||||
*/
|
||||
private void checkForWarningSize() {
|
||||
public void dumpBusyConnectionInformation() {
|
||||
getBusyConnectionInformation(true);
|
||||
}
|
||||
|
||||
// the the total number of connections that we can add
|
||||
// to the pool before it hits the maximum
|
||||
int availableGrowth = (maxSize - totalConnections());
|
||||
/**
|
||||
* Returns information describing connections that are currently being used.
|
||||
*/
|
||||
private String getBusyConnectionInformation(boolean toLogger) {
|
||||
|
||||
if (availableGrowth < warningSize) {
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
|
||||
closeBusyConnections(leakTimeMinutes);
|
||||
return busyList.getBusyConnectionInformation(toLogger);
|
||||
|
||||
String msg = "DataSourcePool [" + name + "] is [" + availableGrowth+ "] connections from its maximum size.";
|
||||
pool.notifyWarning(msg);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public String getBusyConnectionInformation() {
|
||||
return getBusyConnectionInformation(false);
|
||||
}
|
||||
|
||||
public void dumpBusyConnectionInformation() {
|
||||
getBusyConnectionInformation(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information describing connections that are currently being used.
|
||||
*/
|
||||
private String getBusyConnectionInformation(boolean toLogger) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
try {
|
||||
}
|
||||
|
||||
return busyList.getBusyConnectionInformation(toLogger);
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+19
-21
@@ -7,13 +7,13 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
* Collects load statistics for a PooledConnection.
|
||||
*/
|
||||
public class PooledConnectionStatistics {
|
||||
|
||||
|
||||
private final AtomicLong count = new AtomicLong();
|
||||
|
||||
|
||||
private final AtomicLong errorCount = new AtomicLong();
|
||||
|
||||
|
||||
private final AtomicLong hwmNanos = new AtomicLong();
|
||||
|
||||
|
||||
private final AtomicLong totalNanos = new AtomicLong();
|
||||
|
||||
private final AtomicLong collectionStart;
|
||||
@@ -21,22 +21,22 @@ public class PooledConnectionStatistics {
|
||||
public PooledConnectionStatistics() {
|
||||
this.collectionStart = new AtomicLong(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add statistics from another collector.
|
||||
*/
|
||||
public void add(PooledConnectionStatistics other) {
|
||||
|
||||
|
||||
errorCount.addAndGet(other.getErrorCount());
|
||||
totalNanos.addAndGet(other.totalNanos.get());
|
||||
count.addAndGet(other.getCount());
|
||||
|
||||
|
||||
final long otherHwm = other.hwmNanos.get();
|
||||
if (otherHwm > hwmNanos.get()) {
|
||||
hwmNanos.set(otherHwm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add some time duration to the statistics.
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public class PooledConnectionStatistics {
|
||||
|
||||
// This will be done in pretty much single threaded fashion
|
||||
// as the Connections generally are not shared across threads
|
||||
|
||||
|
||||
if (hasError) {
|
||||
errorCount.incrementAndGet();
|
||||
}
|
||||
@@ -54,11 +54,11 @@ public class PooledConnectionStatistics {
|
||||
hwmNanos.set(durationNanos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "count["+count+"] errors["+errorCount+"] totalMicros["+getTotalMicros()+"] hwmMicros["+getHwmMicros()+"]";
|
||||
return "count[" + count + "] errors[" + errorCount + "] totalMicros[" + getTotalMicros() + "] hwmMicros[" + getHwmMicros() + "]";
|
||||
}
|
||||
|
||||
|
||||
public long getCollectionStart() {
|
||||
return collectionStart.get();
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class PooledConnectionStatistics {
|
||||
public long getTotalMicros() {
|
||||
return TimeUnit.MICROSECONDS.convert(totalNanos.get(), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
|
||||
|
||||
public long getHwmMicros() {
|
||||
return TimeUnit.MICROSECONDS.convert(hwmNanos.get(), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
@@ -101,16 +101,16 @@ public class PooledConnectionStatistics {
|
||||
* </p>
|
||||
*/
|
||||
public static class LoadValues {
|
||||
|
||||
|
||||
private long collectionStart;
|
||||
private long count;
|
||||
private long errorCount;
|
||||
private long hwmMicros;
|
||||
private long totalMicros;
|
||||
|
||||
|
||||
public LoadValues() {
|
||||
}
|
||||
|
||||
|
||||
public LoadValues(long collectionStart, long count, long errorCount, long hwmMicros, long totalMicros) {
|
||||
this.collectionStart = collectionStart;
|
||||
this.count = count;
|
||||
@@ -128,7 +128,7 @@ public class PooledConnectionStatistics {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "count["+count+"] errors["+errorCount+"] totalMicros["+totalMicros+"] hwmMicros["+hwmMicros+"] avgMicros["+getAvgMicros()+"]";
|
||||
return "count[" + count + "] errors[" + errorCount + "] totalMicros[" + totalMicros + "] hwmMicros[" + hwmMicros + "] avgMicros[" + getAvgMicros() + "]";
|
||||
}
|
||||
|
||||
public long getCollectionStart() {
|
||||
@@ -150,13 +150,11 @@ public class PooledConnectionStatistics {
|
||||
public long getTotalMicros() {
|
||||
return totalMicros;
|
||||
}
|
||||
|
||||
|
||||
public long getAvgMicros() {
|
||||
return (count == 0) ? 0 : totalMicros/count;
|
||||
return (count == 0) ? 0 : totalMicros / count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,89 +10,89 @@ import java.util.Random;
|
||||
*/
|
||||
public class Prefix {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Prefix.class);
|
||||
|
||||
private static final int[] oa = { 50, 12, 4, 6, 8, 10, 7, 23, 45, 23, 6, 9, 12, 2, 8, 34 };
|
||||
private static final Logger logger = LoggerFactory.getLogger(Prefix.class);
|
||||
|
||||
public static String getProp(String prop) {
|
||||
String v = dec(prop);
|
||||
int p = v.indexOf(":");
|
||||
return v.substring(1, p);
|
||||
}
|
||||
private static final int[] oa = {50, 12, 4, 6, 8, 10, 7, 23, 45, 23, 6, 9, 12, 2, 8, 34};
|
||||
|
||||
public static void main(String[] args) {
|
||||
String m = e(args[0]);
|
||||
logger.info("[" + m + "]");
|
||||
String o = getProp(m);
|
||||
logger.info("[" + o + "]");
|
||||
}
|
||||
public static String getProp(String prop) {
|
||||
String v = dec(prop);
|
||||
int p = v.indexOf(":");
|
||||
return v.substring(1, p);
|
||||
}
|
||||
|
||||
public static String e(String msg) {
|
||||
msg = elen(msg, 40);
|
||||
return enc(msg);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
String m = e(args[0]);
|
||||
logger.info("[" + m + "]");
|
||||
String o = getProp(m);
|
||||
logger.info("[" + o + "]");
|
||||
}
|
||||
|
||||
public static byte az(byte c, int offset) {
|
||||
public static String e(String msg) {
|
||||
msg = elen(msg, 40);
|
||||
return enc(msg);
|
||||
}
|
||||
|
||||
int z = c + offset;
|
||||
if (z > 122) {
|
||||
// dp("z> "+z);
|
||||
z = z - 122 + 48 - 1;
|
||||
}
|
||||
// dp("z="+z+" c:"+(int)c);
|
||||
return (byte) z;
|
||||
}
|
||||
public static byte az(byte c, int offset) {
|
||||
|
||||
public static byte bz(byte c, int offset) {
|
||||
int z = c - offset;
|
||||
if (z < (48)) {
|
||||
// dp("z< "+z);
|
||||
z = z + 122 - 48 + 1;
|
||||
}
|
||||
return (byte) z;
|
||||
}
|
||||
int z = c + offset;
|
||||
if (z > 122) {
|
||||
// dp("z> "+z);
|
||||
z = z - 122 + 48 - 1;
|
||||
}
|
||||
// dp("z="+z+" c:"+(int)c);
|
||||
return (byte) z;
|
||||
}
|
||||
|
||||
public static String enc(String msg) {
|
||||
byte[] msgbytes = msg.getBytes();
|
||||
byte[] encbytes = new byte[msgbytes.length + 1];
|
||||
Random r = new Random();
|
||||
int key = r.nextInt(70);
|
||||
public static byte bz(byte c, int offset) {
|
||||
int z = c - offset;
|
||||
if (z < (48)) {
|
||||
// dp("z< "+z);
|
||||
z = z + 122 - 48 + 1;
|
||||
}
|
||||
return (byte) z;
|
||||
}
|
||||
|
||||
char k = (char) (key + 48);
|
||||
public static String enc(String msg) {
|
||||
byte[] msgbytes = msg.getBytes();
|
||||
byte[] encbytes = new byte[msgbytes.length + 1];
|
||||
Random r = new Random();
|
||||
int key = r.nextInt(70);
|
||||
|
||||
encbytes[0] = az((byte) k, oa[0]);
|
||||
// dp("key:"+key+" encbytes[0]:"+(byte)encbytes[0]);
|
||||
char k = (char) (key + 48);
|
||||
|
||||
encbytes[0] = az((byte) k, oa[0]);
|
||||
// dp("key:"+key+" encbytes[0]:"+(byte)encbytes[0]);
|
||||
for (int i = 1; i < (msgbytes.length + 1); i++) {
|
||||
encbytes[i] = az(msgbytes[i - 1], (oa[(i + key) % oa.length]));
|
||||
}
|
||||
return new String(encbytes);
|
||||
}
|
||||
encbytes[i] = az(msgbytes[i - 1], (oa[(i + key) % oa.length]));
|
||||
}
|
||||
return new String(encbytes);
|
||||
}
|
||||
|
||||
public static String dec(String msg) {
|
||||
byte[] msgbytes = msg.getBytes();
|
||||
byte[] encbytes = new byte[msgbytes.length];
|
||||
public static String dec(String msg) {
|
||||
byte[] msgbytes = msg.getBytes();
|
||||
byte[] encbytes = new byte[msgbytes.length];
|
||||
|
||||
encbytes[0] = bz(msgbytes[0], oa[0]);
|
||||
byte key = encbytes[0];
|
||||
int ios = (key - 48);
|
||||
for (int i = 1; i < msgbytes.length; i++) {
|
||||
encbytes[i] = bz(msgbytes[i], oa[(i + ios) % oa.length]);
|
||||
}
|
||||
return new String(encbytes);
|
||||
}
|
||||
encbytes[0] = bz(msgbytes[0], oa[0]);
|
||||
byte key = encbytes[0];
|
||||
int ios = (key - 48);
|
||||
for (int i = 1; i < msgbytes.length; i++) {
|
||||
encbytes[i] = bz(msgbytes[i], oa[(i + ios) % oa.length]);
|
||||
}
|
||||
return new String(encbytes);
|
||||
}
|
||||
|
||||
public static String elen(String msg, int len) {
|
||||
Random r = new Random();
|
||||
if (msg.length() < len) {
|
||||
int max = len - msg.length();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(msg).append(":");
|
||||
for (int i = 1; i < max; i++) {
|
||||
int bc = r.nextInt(122 - 48);
|
||||
sb.append(Character.toString((char) (bc + 48)));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
public static String elen(String msg, int len) {
|
||||
Random r = new Random();
|
||||
if (msg.length() < len) {
|
||||
int max = len - msg.length();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(msg).append(":");
|
||||
for (int i = 1; i < max; i++) {
|
||||
int bc = r.nextInt(122 - 48);
|
||||
sb.append(Character.toString((char) (bc + 48)));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,103 +12,103 @@ import java.util.Map;
|
||||
*/
|
||||
public class PstmtCache extends LinkedHashMap<String, ExtendedPreparedStatement> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PstmtCache.class);
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PstmtCache.class);
|
||||
|
||||
static final long serialVersionUID = -3096406924865550697L;
|
||||
|
||||
/**
|
||||
* The name of the cache, for tracing purposes.
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* The maximum size of the cache. When this is exceeded the oldest entry is removed.
|
||||
*/
|
||||
private final int maxSize;
|
||||
/**
|
||||
* The name of the cache, for tracing purposes.
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* The total number of entries removed from this cache.
|
||||
*/
|
||||
private int removeCounter;
|
||||
/**
|
||||
* The maximum size of the cache. When this is exceeded the oldest entry is removed.
|
||||
*/
|
||||
private final int maxSize;
|
||||
|
||||
/**
|
||||
* The number of get hits.
|
||||
*/
|
||||
private int hitCounter;
|
||||
/**
|
||||
* The total number of entries removed from this cache.
|
||||
*/
|
||||
private int removeCounter;
|
||||
|
||||
/**
|
||||
* The number of get() misses.
|
||||
*/
|
||||
private int missCounter;
|
||||
/**
|
||||
* The number of get hits.
|
||||
*/
|
||||
private int hitCounter;
|
||||
|
||||
/**
|
||||
* The number of puts into this cache.
|
||||
*/
|
||||
private int putCounter;
|
||||
/**
|
||||
* The number of get() misses.
|
||||
*/
|
||||
private int missCounter;
|
||||
|
||||
public PstmtCache(String cacheName, int maxCacheSize) {
|
||||
/**
|
||||
* The number of puts into this cache.
|
||||
*/
|
||||
private int putCounter;
|
||||
|
||||
// note = access ordered list. This is what gives it the LRU order
|
||||
super(maxCacheSize*3, 0.75f, true);
|
||||
this.cacheName = cacheName;
|
||||
this.maxSize = maxCacheSize;
|
||||
}
|
||||
public PstmtCache(String cacheName, int maxCacheSize) {
|
||||
|
||||
/**
|
||||
* Return a summary description of this cache.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return "size["+size()+"] max["+maxSize+"] hits["+hitCounter+"] miss["+missCounter+"] hitRatio["+getHitRatio()+"] removes["+removeCounter+"]";
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current maximum size of the cache.
|
||||
*/
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
// note = access ordered list. This is what gives it the LRU order
|
||||
super(maxCacheSize * 3, 0.75f, true);
|
||||
this.cacheName = cacheName;
|
||||
this.maxSize = maxCacheSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hit ratio. A number between 0 and 100 indicating the number of
|
||||
* hits to misses. A number approaching 100 is desirable.
|
||||
*/
|
||||
public int getHitRatio() {
|
||||
if (hitCounter == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return hitCounter*100/(hitCounter+missCounter);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return a summary description of this cache.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return "size[" + size() + "] max[" + maxSize + "] hits[" + hitCounter + "] miss[" + missCounter + "] hitRatio[" + getHitRatio() + "] removes[" + removeCounter + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of hits against this cache.
|
||||
*/
|
||||
public int getHitCounter() {
|
||||
return hitCounter;
|
||||
}
|
||||
/**
|
||||
* returns the current maximum size of the cache.
|
||||
*/
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of misses against this cache.
|
||||
*/
|
||||
public int getMissCounter() {
|
||||
return missCounter;
|
||||
}
|
||||
/**
|
||||
* Gets the hit ratio. A number between 0 and 100 indicating the number of
|
||||
* hits to misses. A number approaching 100 is desirable.
|
||||
*/
|
||||
public int getHitRatio() {
|
||||
if (hitCounter == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return hitCounter * 100 / (hitCounter + missCounter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of puts against this cache.
|
||||
*/
|
||||
public int getPutCounter() {
|
||||
return putCounter;
|
||||
}
|
||||
/**
|
||||
* The total number of hits against this cache.
|
||||
*/
|
||||
public int getHitCounter() {
|
||||
return hitCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to add the returning statement to the cache. If there is already a
|
||||
* matching ExtendedPreparedStatement in the cache return false else add
|
||||
* the statement to the cache and return true.
|
||||
*/
|
||||
public boolean returnStatement(ExtendedPreparedStatement pstmt) {
|
||||
|
||||
ExtendedPreparedStatement alreadyInCache = super.get(pstmt.getCacheKey());
|
||||
/**
|
||||
* The total number of misses against this cache.
|
||||
*/
|
||||
public int getMissCounter() {
|
||||
return missCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of puts against this cache.
|
||||
*/
|
||||
public int getPutCounter() {
|
||||
return putCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to add the returning statement to the cache. If there is already a
|
||||
* matching ExtendedPreparedStatement in the cache return false else add
|
||||
* the statement to the cache and return true.
|
||||
*/
|
||||
public boolean returnStatement(ExtendedPreparedStatement pstmt) {
|
||||
|
||||
ExtendedPreparedStatement alreadyInCache = super.get(pstmt.getCacheKey());
|
||||
if (alreadyInCache != null) {
|
||||
return false;
|
||||
}
|
||||
@@ -117,67 +117,67 @@ public class PstmtCache extends LinkedHashMap<String, ExtendedPreparedStatement>
|
||||
// PStmts when the cache has hit its maximum size.
|
||||
put(pstmt.getCacheKey(), pstmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* additionally maintains hit and miss statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement get(Object key) {
|
||||
}
|
||||
|
||||
ExtendedPreparedStatement o = super.get(key);
|
||||
if (o == null) {
|
||||
missCounter++;
|
||||
} else {
|
||||
hitCounter++;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
/**
|
||||
* additionally maintains hit and miss statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement get(Object key) {
|
||||
|
||||
/**
|
||||
* additionally maintains hit and miss statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement remove(Object key) {
|
||||
ExtendedPreparedStatement o = super.get(key);
|
||||
if (o == null) {
|
||||
missCounter++;
|
||||
} else {
|
||||
hitCounter++;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
ExtendedPreparedStatement o = super.remove(key);
|
||||
if (o == null) {
|
||||
missCounter++;
|
||||
} else {
|
||||
hitCounter++;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
/**
|
||||
* additionally maintains hit and miss statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement remove(Object key) {
|
||||
|
||||
/**
|
||||
* additionally maintains put counter statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement put(String key, ExtendedPreparedStatement value) {
|
||||
ExtendedPreparedStatement o = super.remove(key);
|
||||
if (o == null) {
|
||||
missCounter++;
|
||||
} else {
|
||||
hitCounter++;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
putCounter++;
|
||||
return super.put(key, value);
|
||||
}
|
||||
/**
|
||||
* additionally maintains put counter statistics.
|
||||
*/
|
||||
public ExtendedPreparedStatement put(String key, ExtendedPreparedStatement value) {
|
||||
|
||||
putCounter++;
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* will check to see if we need to remove entries and
|
||||
* if so call the cacheCleanup.cleanupEldestLRUCacheEntry() if
|
||||
* one has been set.
|
||||
*/
|
||||
protected boolean removeEldestEntry(Map.Entry<String, ExtendedPreparedStatement> eldest) {
|
||||
|
||||
if (size() < maxSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
removeCounter++;
|
||||
|
||||
try {
|
||||
ExtendedPreparedStatement pstmt = eldest.getValue();
|
||||
pstmt.closeDestroy();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error closing ExtendedPreparedStatement", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* will check to see if we need to remove entries and
|
||||
* if so call the cacheCleanup.cleanupEldestLRUCacheEntry() if
|
||||
* one has been set.
|
||||
*/
|
||||
protected boolean removeEldestEntry(Map.Entry<String,ExtendedPreparedStatement> eldest) {
|
||||
|
||||
if (size() < maxSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
removeCounter++;
|
||||
|
||||
try {
|
||||
ExtendedPreparedStatement pstmt = eldest.getValue();
|
||||
pstmt.closeDestroy();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error closing ExtendedPreparedStatement", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,66 +4,64 @@ import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Helper object that can convert between transaction isolation descriptions and values.
|
||||
*
|
||||
*/
|
||||
public class TransactionIsolation {
|
||||
|
||||
|
||||
/**
|
||||
* return the isolation level for a given string description.
|
||||
*/
|
||||
public static int getLevel(String level) {
|
||||
level = level.toUpperCase();
|
||||
if (level.startsWith("TRANSACTION")){
|
||||
level = level.substring("TRANSACTION".length());
|
||||
}
|
||||
level = level.replace("_", "");
|
||||
if ("NONE".equalsIgnoreCase(level)){
|
||||
return Connection.TRANSACTION_NONE;
|
||||
}
|
||||
if ("READCOMMITTED".equalsIgnoreCase(level)){
|
||||
return Connection.TRANSACTION_READ_COMMITTED;
|
||||
}
|
||||
if ("READUNCOMMITTED".equalsIgnoreCase(level)){
|
||||
return Connection.TRANSACTION_READ_UNCOMMITTED;
|
||||
}
|
||||
if ("REPEATABLEREAD".equalsIgnoreCase(level)){
|
||||
return Connection.TRANSACTION_REPEATABLE_READ;
|
||||
}
|
||||
if ("SERIALIZABLE".equalsIgnoreCase(level)){
|
||||
return Connection.TRANSACTION_SERIALIZABLE;
|
||||
}
|
||||
/**
|
||||
* return the isolation level for a given string description.
|
||||
*/
|
||||
public static int getLevel(String level) {
|
||||
level = level.toUpperCase();
|
||||
if (level.startsWith("TRANSACTION")) {
|
||||
level = level.substring("TRANSACTION".length());
|
||||
}
|
||||
level = level.replace("_", "");
|
||||
if ("NONE".equalsIgnoreCase(level)) {
|
||||
return Connection.TRANSACTION_NONE;
|
||||
}
|
||||
if ("READCOMMITTED".equalsIgnoreCase(level)) {
|
||||
return Connection.TRANSACTION_READ_COMMITTED;
|
||||
}
|
||||
if ("READUNCOMMITTED".equalsIgnoreCase(level)) {
|
||||
return Connection.TRANSACTION_READ_UNCOMMITTED;
|
||||
}
|
||||
if ("REPEATABLEREAD".equalsIgnoreCase(level)) {
|
||||
return Connection.TRANSACTION_REPEATABLE_READ;
|
||||
}
|
||||
if ("SERIALIZABLE".equalsIgnoreCase(level)) {
|
||||
return Connection.TRANSACTION_SERIALIZABLE;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not known.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string description of the transaction isolation level specified.
|
||||
* <p>Returned value is one of NONE, READ_COMMITTED,READ_UNCOMMITTED,
|
||||
* REPEATABLE_READ or SERIALIZABLE.</p>
|
||||
*
|
||||
* @param level the transaction isolation level as per java.sql.Connection
|
||||
* @return the level description as a string.
|
||||
*/
|
||||
public static String getLevelDescription(int level) {
|
||||
switch (level) {
|
||||
case Connection.TRANSACTION_NONE :
|
||||
return "NONE";
|
||||
case Connection.TRANSACTION_READ_COMMITTED :
|
||||
return "READ_COMMITTED";
|
||||
case Connection.TRANSACTION_READ_UNCOMMITTED :
|
||||
return "READ_UNCOMMITTED";
|
||||
case Connection.TRANSACTION_REPEATABLE_READ :
|
||||
return "REPEATABLE_READ";
|
||||
case Connection.TRANSACTION_SERIALIZABLE :
|
||||
return "SERIALIZABLE";
|
||||
case -1 :
|
||||
return "NotSet";
|
||||
default :
|
||||
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not defined.");
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not known.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string description of the transaction isolation level specified.
|
||||
* <p>Returned value is one of NONE, READ_COMMITTED,READ_UNCOMMITTED,
|
||||
* REPEATABLE_READ or SERIALIZABLE.</p>
|
||||
*
|
||||
* @param level the transaction isolation level as per java.sql.Connection
|
||||
* @return the level description as a string.
|
||||
*/
|
||||
public static String getLevelDescription(int level) {
|
||||
switch (level) {
|
||||
case Connection.TRANSACTION_NONE:
|
||||
return "NONE";
|
||||
case Connection.TRANSACTION_READ_COMMITTED:
|
||||
return "READ_COMMITTED";
|
||||
case Connection.TRANSACTION_READ_UNCOMMITTED:
|
||||
return "READ_UNCOMMITTED";
|
||||
case Connection.TRANSACTION_REPEATABLE_READ:
|
||||
return "REPEATABLE_READ";
|
||||
case Connection.TRANSACTION_SERIALIZABLE:
|
||||
return "SERIALIZABLE";
|
||||
case -1:
|
||||
return "NotSet";
|
||||
default:
|
||||
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not defined.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE>AvajeLib</TITLE>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
|
||||
<TITLE>AvajeLib</TITLE>
|
||||
</HEAD>
|
||||
<Body BGCOLOR="#ffffff">
|
||||
Enhanced JDBC objects and connection pool.
|
||||
|
||||
Reference in New Issue
Block a user