KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > dbm > PoolItem


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * Initial developer(s): ____________________________________.
22  * Contributor(s):
23  * 01/11/06 Christophe Ney cney@batisseurs.com for Lutris Technologies
24  * Added ResourceManagerListener mechanism to remove ThreadData
25  * dependency.
26  *
27  * --------------------------------------------------------------------------
28  * $Id: PoolItem.java,v 1.21 2005/06/30 14:50:07 durieuxp Exp $
29  * --------------------------------------------------------------------------
30  */

31
32
33 package org.objectweb.jonas.dbm;
34
35 import javax.sql.XAConnection JavaDoc;
36 import javax.transaction.Synchronization JavaDoc;
37 import javax.transaction.Transaction JavaDoc;
38
39 import org.objectweb.jonas.common.Log;
40 import org.objectweb.transaction.jta.ResourceManagerEvent;
41 import org.objectweb.util.monolog.api.BasicLevel;
42 import org.objectweb.util.monolog.api.Logger;
43
44 /**
45  * This class represents a connection stored in the pool.
46  * It may be in different states:
47  * - available and reuseable for this user (open=0, tx=null)
48  * - reusable for the same transaction, not already committed (open=?, tx!=null)
49  * - still open, but not involved in a Tx (open=1, tx=null)
50  * These 2 cases must be considered: close after commit, commit after close.
51  * We cannot suppose what shema the user will use and we must handle both correctly.
52  */

53 public class PoolItem implements ResourceManagerEvent, Synchronization JavaDoc {
54
55     /**
56      * Count of items. Used for debugging
57      */

58     private static int count = 0;
59
60     private XAConnection JavaDoc xaConn; // the pooled connection
61
private String JavaDoc user; // the user name
62
private int open; // >0 if connection is open
63
private Transaction JavaDoc tx; // transaction the connection is involved with
64
private Transaction JavaDoc enlistedInTx; /// current transaction in case of late enlistment
65
private boolean rme = false; // true if registered as ResourceManagerEvent
66
private long deathTime; // When it is expected to die (for closed connections)
67
private long closeTime; // When it is expected to be closed (for opened connections)
68
private int number;
69     private Pool pool;
70     private Logger logger = null;
71
72     /*
73      * constructor used by newConnection()
74      */

75     public PoolItem(Pool pool, XAConnection JavaDoc xac, String JavaDoc user, Logger logger) {
76         this.pool = pool;
77         this.xaConn = xac;
78         this.user = user;
79         open = 0;
80         deathTime = System.currentTimeMillis() + pool.getMaxAgeMilli();
81         number = count++;
82         this.logger = logger;
83     }
84
85     /*
86      * string form for debugging
87      */

88     public String JavaDoc toString() {
89         Integer JavaDoc i = new Integer JavaDoc(number);
90         return i.toString();
91     }
92
93     /**
94      * implementation of resource manager event
95      */

96     public void enlistConnection(Transaction JavaDoc transaction) throws javax.transaction.SystemException JavaDoc {
97         try {
98             if (rme) {
99                 xaConn.getConnection().setAutoCommit(false);
100                 // the tx value of the pool item does not match with the enlisted value !?
101
enlistedInTx = transaction;
102                 // enlist the resource
103
if (logger.isLoggable(BasicLevel.DEBUG)) {
104                     logger.log(BasicLevel.DEBUG, "enlist XAResource on " + transaction);
105                 }
106                 transaction.enlistResource(xaConn.getXAResource());
107             }
108         } catch (javax.transaction.RollbackException JavaDoc e) {
109             javax.transaction.SystemException JavaDoc se = new javax.transaction.SystemException JavaDoc("Unexpected RollbackException exception");
110             se.initCause(e);
111             throw se;
112         } catch (java.sql.SQLException JavaDoc e) {
113             javax.transaction.SystemException JavaDoc se = new javax.transaction.SystemException JavaDoc("Unexpected SQL exception");
114             se.initCause(e);
115             throw se;
116         }
117     }
118
119     /**
120      * synchronization implementation
121      */

122     public void beforeCompletion() {
123         // nothing to do
124
}
125
126     /**
127      * synchronization implementation
128      */

129     public void afterCompletion(int status) {
130         if (tx == null ) {
131             logger.log(BasicLevel.ERROR, "NO TX!");
132         }
133         pool.freeConnections(tx != null ? tx : enlistedInTx);
134     }
135
136     /**
137      * @return true if connection max age has expired
138      */

139     public boolean isAged() {
140         return (deathTime < System.currentTimeMillis());
141     }
142
143     /**
144      * @return true if connection is still open
145      */

146     public boolean isOpen() {
147         return (open > 0);
148     }
149
150     /**
151      * @return open count
152      */

153     public int getOpenCount() {
154         return open;
155     }
156
157     /**
158      * Check if the connection has been unused for too long time.
159      * This occurs usually when the caller forgot to call close().
160      * @return true if open time has been reached, and not involved in a tx.
161      */

162     public boolean inactive() {
163         return (open > 0 && tx == null && enlistedInTx == null && closeTime < System.currentTimeMillis());
164     }
165
166     /**
167      * @return true if connection is closed
168      */

169     public boolean isClosed() {
170         return (open <= 0);
171     }
172
173     /**
174      * Notify as opened
175      */

176     public void open() {
177         open++;
178         closeTime = System.currentTimeMillis() + pool.getMaxOpenTimeMilli();
179     }
180
181     /**
182      * notify as closed
183      * @return true if normal close.
184      */

185     public boolean close() {
186         open--;
187         if (open < 0) {
188             logger.log(BasicLevel.WARN, "connection was already closed");
189             open = 0;
190             return false;
191         }
192         if (tx == null && open > 0) {
193             logger.log(BasicLevel.ERROR, "connection-open counter overflow");
194             open = 0;
195         }
196         return true;
197     }
198
199     /**
200      * @return the associated XAConnection
201      */

202     public XAConnection JavaDoc getXACon() {
203         return xaConn;
204     }
205
206     /**
207      * Set the associated transaction
208      * @param tx Transaction
209      */

210     public void setTx(Transaction JavaDoc tx) {
211         this.tx = tx;
212     }
213
214     /**
215      * @return the Transaction
216      */

217     public Transaction JavaDoc getTx() {
218         return tx;
219     }
220
221     /**
222      * @return true if registered as RME
223      */

224     public boolean isRME() {
225         return rme;
226     }
227
228     /**
229      * set/unset as RME
230      */

231     public void setRME(boolean rme) {
232         this.rme = rme;
233     }
234
235     /**
236      * remove this item
237      */

238     public void remove() {
239         // Close the physical connection
240
try {
241             xaConn.close();
242         } catch (java.sql.SQLException JavaDoc ign) {
243             logger.log(BasicLevel.ERROR, "Could not close Connection: ", ign);
244         }
245
246         // remove all references (for GC)
247
xaConn = null;
248         tx = null;
249         enlistedInTx = null;
250     }
251 }
252
Popular Tags