package jef.database.innerpool;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import jef.common.Callback;
import jef.common.pool.PoolStatus;
import jef.database.ConnectInfo;
import jef.database.DbMetaData;
import jef.database.dialect.DatabaseDialect;
import org.easyframe.enterprise.spring.TransactionMode;
import com.google.common.collect.MapMaker;
/**
* 虚连接池,实际上所有连接都是用时打开,用完关闭的。<br>
* 当使用第三方连接池的时候使用。
*
* @author jiyi
*
*/
final class SingleDummyConnectionPool implements IUserManagedPool {
private DataSource ds;
final Map<Object, SingleConnection> map = new MapMaker().concurrencyLevel(12).weakKeys().makeMap();
private final AtomicLong pollCount = new AtomicLong();
private final AtomicLong offerCount = new AtomicLong();
private final DbMetaData metadata;
SingleDummyConnectionPool(DataSource ds) {
this.ds = ds;
this.metadata = new DbMetaData(ds, this, null);
// 反向修正
metadata.getProfile().accept(metadata);
PoolReleaseThread.getInstance().addPool(this);
}
public SingleConnection poll() throws SQLException {
return getConnection(Thread.currentThread());
}
public SingleConnection getConnection(Object transaction) throws SQLException {
pollCount.incrementAndGet();
SingleConnection conn = map.get(transaction);
if (conn == null) {
conn = new SingleConnection(ds.getConnection(), this);
map.put(transaction, conn);
conn.setUsedByObject(transaction);
} else {
conn.addUsedByObject();
}
// conn.ensureOpen();连接可用性由第三方连接池保证,此处不用处理
return conn;
}
public void close() throws SQLException {
for (IConnection conn : map.values()) {
conn.closePhysical();
}
map.clear();
PoolReleaseThread.getInstance().removePool(this);
System.out.println("pollCount:" + pollCount + " offer count:" + offerCount);
}
public DataSource getDatasource() {
return ds;
}
public PoolStatus getStatus() {
int size = map.size();
return new PoolStatus(0, 0, size, size, 0);
}
public void offer(ReentrantConnection conn) {
offerCount.incrementAndGet();
if (conn != null) {
// 处理内部的记录数据
Object o = conn.popUsedByObject();
if (o == null)
return;// 不是真正归还
IConnection conn1 = map.remove(o);
conn.closePhysical();
if (conn1 != conn) {
throw new IllegalStateException("The connection returned not match.");
}
}
}
public Collection<String> getAllDatasourceNames() {
return Collections.emptyList();
}
public void closeConnectionTillMin() {
}
public DbMetaData getMetadata(String dbkey) {
return metadata;
}
public DatabaseDialect getProfile(String dbkey) {
return metadata.getProfile();
}
public ConnectInfo getInfo(String dbkey) {
return getMetadata(dbkey).getInfo();
}
public void registeDbInitCallback(Callback<String, SQLException> callback) {
if (callback != null) {
try {
callback.call(null);
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
}
public boolean isRouting() {
return false;
}
public boolean isDummy() {
return true;
}
private TransactionMode txMode;
@Override
public IUserManagedPool setTransactionMode(TransactionMode txMode) {
this.txMode = txMode;
return this;
}
@Override
public TransactionMode getTransactionMode() {
return txMode;
}
}