00001
00033 package org.objectweb.jonas.dbm;
00034
00035 import javax.sql.XAConnection;
00036 import javax.transaction.Synchronization;
00037 import javax.transaction.Transaction;
00038
00039 import org.objectweb.jonas.common.Log;
00040 import org.objectweb.transaction.jta.ResourceManagerEvent;
00041 import org.objectweb.util.monolog.api.BasicLevel;
00042 import org.objectweb.util.monolog.api.Logger;
00043
00053 public class PoolItem implements ResourceManagerEvent, Synchronization {
00054
00058 private static int count = 0;
00059
00060 private XAConnection xaConn;
00061 private String user;
00062 private int open;
00063 private Transaction tx;
00064 private Transaction enlistedInTx;
00065 private boolean rme = false;
00066 private long deathTime;
00067 private long closeTime;
00068 private int number;
00069 private Pool pool;
00070 private Logger logger = null;
00071
00072
00073
00074
00075 public PoolItem(Pool pool, XAConnection xac, String user) {
00076 this.pool = pool;
00077 this.xaConn = xac;
00078 this.user = user;
00079 open = 0;
00080 deathTime = System.currentTimeMillis() + pool.getMaxAgeMilli();
00081 number = count++;
00082 logger = Log.getLogger(Log.JONAS_DBM_PREFIX);
00083 }
00084
00085
00086
00087
00088 public String toString() {
00089 Integer i = new Integer(number);
00090 return i.toString();
00091 }
00092
00096 public void enlistConnection(Transaction transaction) throws javax.transaction.SystemException {
00097 try {
00098 if (rme) {
00099 xaConn.getConnection().setAutoCommit(false);
00100
00101 enlistedInTx = transaction;
00102
00103 if (logger.isLoggable(BasicLevel.DEBUG))
00104 logger.log(BasicLevel.DEBUG, "enlist XAResource on " + transaction);
00105 transaction.enlistResource(xaConn.getXAResource());
00106 }
00107 } catch (javax.transaction.RollbackException e) {
00108 throw new javax.transaction.SystemException("Unexpected RollbackException exception: "+e.getMessage());
00109 } catch (java.sql.SQLException e) {
00110 throw new javax.transaction.SystemException("Unexpected SQL exception: "+e.getMessage());
00111 }
00112 }
00113
00117 public void beforeCompletion() {
00118
00119 }
00120
00124 public void afterCompletion(int status) {
00125 if (tx == null ) {
00126 logger.log(BasicLevel.ERROR, "NO TX!");
00127 }
00128 pool.freeConnections(tx != null ? tx : enlistedInTx);
00129 }
00130
00134 public boolean isAged() {
00135 return (deathTime < System.currentTimeMillis());
00136 }
00137
00141 public boolean isOpen() {
00142 return (open > 0);
00143 }
00144
00148 public int getOpenCount() {
00149 return open;
00150 }
00151
00157 public boolean inactive() {
00158 return (open > 0 && tx == null && enlistedInTx == null && closeTime < System.currentTimeMillis());
00159 }
00160
00164 public boolean isClosed() {
00165 return (open <= 0);
00166 }
00167
00171 public void open() {
00172 open++;
00173 closeTime = System.currentTimeMillis() + pool.getMaxOpenTimeMilli();
00174 }
00175
00180 public boolean close() {
00181 open--;
00182 if (open < 0) {
00183 logger.log(BasicLevel.WARN, "connection was already closed");
00184 open = 0;
00185 return false;
00186 }
00187 if (tx == null && open > 0) {
00188 logger.log(BasicLevel.ERROR, "connection-open counter overflow");
00189 open = 0;
00190 }
00191 return true;
00192 }
00193
00197 public XAConnection getXACon() {
00198 return xaConn;
00199 }
00200
00205 public void setTx(Transaction tx) {
00206 this.tx = tx;
00207 }
00208
00212 public Transaction getTx() {
00213 return tx;
00214 }
00215
00219 public boolean isRME() {
00220 return rme;
00221 }
00222
00226 public void setRME(boolean rme) {
00227 this.rme = rme;
00228 }
00229
00233 public void remove() {
00234
00235 try {
00236 xaConn.close();
00237 } catch (java.sql.SQLException ign) {
00238 logger.log(BasicLevel.ERROR, "Could not close Connection: " + ign);
00239 }
00240
00241
00242 xaConn = null;
00243 tx = null;
00244 enlistedInTx = null;
00245 }
00246 }