package org.enhydra.jdbc.standard;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.CallableStatement;
import java.util.Hashtable;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
public class StandardXAConnectionHandle extends StandardConnectionHandle {
boolean resetTxonResume =false;
boolean globalTransaction;
public TransactionManager transactionManager;
public Transaction tx;
public StandardXAConnection xacon;
public boolean thisAutoCommit = true;
public StandardXAConnectionHandle(
StandardXAConnection pooledCon,
Hashtable preparedStatementCache,
int preparedStmtCacheSize,
TransactionManager tm) {
super(pooledCon, preparedStatementCache, preparedStmtCacheSize);
xacon = pooledCon;
transactionManager = tm;
log = pooledCon.dataSource.log;
}
public void setTransactionManager(TransactionManager tm) {
this.transactionManager = tm;
}
synchronized public void close() throws SQLException {
Transaction ttx = tx;
super.close();
log.debug("StandardXAConnectionHandle:close");
log.debug(
"StandardXAConnectionHandle:close globalTransaction='"
+ globalTransaction
+ "' con.getAutoCommit='"
+ con.getAutoCommit()
+ "' ttx='"
+ ttx
+ "'");
if ((!con.getAutoCommit()) && (ttx == null)) {
log.debug(
"StandardXAConnectionHandle:close rollback the connection");
con.rollback();
con.setAutoCommit(thisAutoCommit);
} else
log.debug("StandardXAConnectionHandle:close do nothing else");
isReallyUsed = false;
log.debug(
"StandardXAConnectionHandle:close AFTER globalTransaction='"
+ globalTransaction
+ "' con.getAutoCommit='"
+ con.getAutoCommit()
+ "' ttx='"
+ ttx
+ "'");
}
void setGlobalTransaction(boolean setting) throws SQLException {
log.debug(
"StandardXAConnectionHandle:setGlobalTransaction gTransaction='"
+ setting
+ "'");
globalTransaction = setting;
con = pooledCon.getPhysicalConnection();
if (con == null)
log.warn(
"StandardXAConnectionHandle:setGlobalTransaction con is null before setupPreparedStatementCache");
else
log.debug(
"StandardXAConnectionHandle:setGlobalTransaction con is *NOT* null before setupPreparedStatementCache");
if(!isClosed())
super.setAutoCommit(!setting);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (globalTransaction)
throw new SQLException("StandardXAConnectionHandle:setAutoCommit This connection is part of a global transaction");
super.setAutoCommit(autoCommit);
}
public void commit() throws SQLException {
if (globalTransaction)
throw new SQLException("StandardXAConnectionHandle:commit:This connection is part of a global transaction");
super.commit();
}
public void rollback() throws SQLException {
if (globalTransaction)
throw new SQLException("StandardXAConnectionHandle:rollback:This connection is part of a global transaction");
super.rollback();
}
synchronized PreparedStatement checkPreparedCache(
String sql,
int type,
int concurrency,
int holdability,
Object lookupKey)
throws SQLException {
PreparedStatement ret = null;
if (preparedStatementCache != null) {
Object obj = preparedStatementCache.get(lookupKey);
if (obj != null) {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object is found");
ret = (PreparedStatement) obj;
try {
ret.clearParameters();
} catch (SQLException e) {
ret = createPreparedStatement(sql, type, concurrency, holdability);
}
preparedStatementCache.remove(lookupKey);
inUse.put(lookupKey, ret);
} else {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object is *NOT* found");
ret = createPreparedStatement(sql, type, concurrency, holdability);
inUse.put(lookupKey, ret);
}
} else {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object the cache is out");
ret = createPreparedStatement(sql, type, concurrency, holdability);
}
log.debug(
"StandardXAConnectionHandle:checkPreparedCache pstmt='"
+ ret.toString()
+ "'");
return ret;
}
synchronized PreparedStatement checkPreparedCache(
String sql,
int autogeneratedkeys,
Object lookupKey)
throws SQLException {
PreparedStatement ret = null;
if (preparedStatementCache != null) {
Object obj = preparedStatementCache.get(lookupKey);
if (obj != null) {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object is found");
ret = (PreparedStatement) obj;
try {
ret.clearParameters();
} catch (SQLException e) {
ret = createPreparedStatement(sql, autogeneratedkeys);
}
preparedStatementCache.remove(lookupKey);
inUse.put(lookupKey, ret);
} else {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object is *NOT* found");
ret = createPreparedStatement(sql, autogeneratedkeys);
inUse.put(lookupKey, ret);
}
} else {
log.debug(
"StandardXAConnectionHandle:checkPreparedCache object the cache is out");
ret = createPreparedStatement(sql, autogeneratedkeys);
}
log.debug(
"StandardXAConnectionHandle:checkPreparedCache pstmt='"
+ ret.toString()
+ "'");
return ret;
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
return prepareStatement(sql, 0, 0, 0);
}
public PreparedStatement prepareStatement(
String sql,
int resultSetType,
int resultSetConcurrency)
throws SQLException {
return prepareStatement(sql, resultSetType, resultSetConcurrency, 0);
}
public PreparedStatement prepareStatement(
String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException {
if (tx == null) {
log.debug("StandardXAConnectionHandle:prepareStatement tx==null");
try {
try {
Transaction ntx = this.getTransaction();
if (ntx != null) {
log.debug(
"StandardXAConnectionHandle:prepareStatement (found a transaction)");
tx = ntx;
xacon.thisAutoCommit = this.getAutoCommit();
if (this.getAutoCommit()) {
this.setAutoCommit(false);
}
try {
tx.enlistResource(xacon.getXAResource());
} catch (RollbackException n) {
log.debug(
"StandardXAConnectionHandle:prepareStatemnet enlistResource exception : "
+ n.toString());
}
} else {
log.debug(
"StandardXAConnectionHandle:prepareStatement (no transaction found)");
}
} catch (SystemException n) {
n.printStackTrace();
throw new SQLException(
"StandardXAConnectionHandle:prepareStatement getTransaction exception: "
+ n.toString());
}
} catch (NullPointerException n) {
n.printStackTrace();
throw new SQLException("StandardXAConnectionHandle:prepareStatement should not be used outside an EJBServer");
}
} else
log.debug("StandardXAConnectionHandle:prepareStatement tx!=null");
isReallyUsed = true;
return new StandardXAPreparedStatement(
this,
sql,
resultSetType,
resultSetConcurrency,
resultSetHoldability);
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException {
if (tx == null) {
log.debug("StandardXAConnectionHandle:prepareStatement tx==null");
try {
try {
Transaction ntx = this.getTransaction();
if (ntx != null) {
log.debug(
"StandardXAConnectionHandle:prepareStatement (found a transaction)");
tx = ntx;
xacon.thisAutoCommit = this.getAutoCommit();
if (this.getAutoCommit()) {
this.setAutoCommit(false);
}
try {
tx.enlistResource(xacon.getXAResource());
} catch (RollbackException n) {
log.debug(
"StandardXAConnectionHandle:prepareStatemnet enlistResource exception : "
+ n.toString());
}
} else {
log.debug(
"StandardXAConnectionHandle:prepareStatement (no transaction found)");
}
} catch (SystemException n) {
n.printStackTrace();
throw new SQLException(
"StandardXAConnectionHandle:prepareStatement getTransaction exception: "
+ n.toString());
}
} catch (NullPointerException n) {
n.printStackTrace();
throw new SQLException("StandardXAConnectionHandle:prepareStatement should not be used outside an EJBServer");
}
} else
log.debug("StandardXAConnectionHandle:prepareStatement tx!=null");
isReallyUsed = true;
return new StandardXAPreparedStatement(
this,
sql,
autoGeneratedKeys);
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
throw new UnsupportedOperationException();
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
throw new UnsupportedOperationException();
}
public CallableStatement prepareCall(
String sql,
int resultSetType,
int resultSetConcurrency)
throws SQLException {
return new StandardXACallableStatement(
this,
sql,
resultSetType,
resultSetConcurrency, 0);
}
public CallableStatement prepareCall(String sql) throws SQLException {
return new StandardXACallableStatement(this, sql, 0, 0, 0);
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
return new StandardXACallableStatement(
this,
sql,
resultSetType,
resultSetConcurrency,
resultSetHoldability);
}
public Statement createStatement() throws SQLException {
return createStatement(0,0,0);
}
public Statement createStatement(
int resultSetType,
int resultSetConcurrency)
throws SQLException {
return createStatement(resultSetType, resultSetConcurrency, 0);
}
public Statement createStatement(
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException {
if (tx == null) {
log.debug("StandardXAConnectionHandle:createStatement tx==null");
try {
try {
Transaction ntx = this.getTransaction();
if (ntx != null) {
log.debug(
"StandardXAConnectionHandle:createStatement (found a transaction)");
tx = ntx;
xacon.thisAutoCommit = this.getAutoCommit();
if (this.getAutoCommit()) {
this.setAutoCommit(false);
}
try {
tx.enlistResource(xacon.getXAResource());
} catch (RollbackException n) {
log.debug(
"StandardXAConnectionHandle:createStatement enlistResource exception: "
+ n.toString());
}
} else {
log.debug(
"StandardXAConnectionHandle:createStatement (no transaction found)");
}
} catch (SystemException n) {
throw new SQLException(
"StandardXAConnectionHandle:createStatement getTransaction exception: "
+ n.toString());
}
} catch (NullPointerException n) {
throw new SQLException(
"StandardXAConnectionHandle:createStatement should not be used outside an EJBServer: "
+ n.toString());
}
}
isReallyUsed = true;
return new StandardXAStatement(this, resultSetType, resultSetConcurrency, resultSetHoldability);
}
private Transaction getTransaction() throws SystemException {
Transaction ntx = null;
if (transactionManager != null) {
ntx = transactionManager.getTransaction();
} else {
log.debug(
"StandardXAConnectionHandle:getTransaction (null transaction manager)");
}
return ntx;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("StandardXAConnectionHandle:\n");
sb.append(" global transaction =<"+this.globalTransaction+ ">\n");
sb.append(" is really used =<"+this.isReallyUsed+ ">\n");
sb.append(" this autoCommit =<"+this.thisAutoCommit+ ">\n");
sb.append(" in use size =<"+this.inUse.size()+ ">\n");
sb.append(" master prepared stmt cache size =<"+this.masterPrepStmtCache.size()+ ">\n");
sb.append(" transaction =<"+this.tx+ ">\n");
sb.append(" connection =<"+this.con.toString()+ ">\n");
return sb.toString();
}
}