package jef.database.innerpool;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import jef.database.DbUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author jiyi
*
*/
final class SingleConnection extends AbstractJDBCConnection implements ReentrantConnection{
private static Logger log = LoggerFactory.getLogger(SingleConnection.class);
/**
* Belongs to the connection pool.
*/
private IPool<ReentrantConnection> parent;
/**
* The connection was locked by the object.
*/
private volatile Object used;
/**
* Reentrant count of the lock.
*/
private volatile int count;
/**
* 构造
*
* @param conn
* @param parent
* @throws SQLException
*/
SingleConnection(Connection connection, IPool<ReentrantConnection> parent) {
this.conn = connection;
this.parent = parent;
}
public void closePhysical() {
if (conn != null) {
DbUtils.closeConnection(conn);
conn = null;
}
}
/////////////////////归还逻辑\重连逻辑\路由逻辑/////////////////////
public void close(){
parent.offer(this);
}
public void ensureOpen() throws SQLException {
if (conn != null && conn.isClosed()) {// 检测到关闭的连接后,提示全面检测
conn=null;
}
if (conn == null) {// 试图创建新连接
long start = System.currentTimeMillis();
DataSource ds = parent.getDatasource();
conn = ds.getConnection();
log.info("Create connection to {}, cost {}ms.", ds, System.currentTimeMillis() - start);
}
}
public void setKey(String key) {
}
/////////////////有效性检查/////////////////
public void setInvalid() {
closePhysical();
}
public boolean checkValid(String testSql) throws SQLException {
if (conn == null)
return true;
PreparedStatement st = conn.prepareStatement(testSql);
try {
st.execute();
return true;
} finally {
DbUtils.close(st);
}
}
public boolean checkValid(int timeout) throws SQLException {
if (conn == null)
return true;
return conn.isValid(timeout);
}
///////////////////重入记录////////////////
public void setUsedByObject(Object user) {
this.used = user;
count++;
}
public Object popUsedByObject() {
if (--count > 0) {
// log.debug("not return connection {} counter:{}.",used,count);
return null;
} else {
Object o = used;
used = null;
return o;
}
}
public void addUsedByObject() {
count++;
}
public boolean isUsed() {
return count > 0;
}
}