KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > NonmanagedTransaction


1 /*
2  * Copyright 2004 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: NonmanagedTransaction.java,v 1.10 2004/01/18 03:01:05 jackknifebarber Exp $
9  */

10
11 package com.triactive.jdo;
12
13 import com.triactive.jdo.store.DatabaseAdapter;
14 import java.sql.Connection JavaDoc;
15 import java.sql.SQLException JavaDoc;
16 import javax.jdo.JDOFatalDataStoreException;
17 import javax.jdo.JDOUnsupportedOptionException;
18 import javax.jdo.PersistenceManager;
19 import javax.sql.DataSource JavaDoc;
20 import javax.transaction.Status JavaDoc;
21 import javax.transaction.Synchronization JavaDoc;
22 import org.apache.log4j.Category;
23
24
25 class NonmanagedTransaction implements Transaction
26 {
27     /**
28      * The system property that selects whether SELECT FOR UPDATE should be used
29      * to fetch objects when the transaction isolation level is READ COMMITTED
30      * or lower. This is the string "com.triactive.jdo.useUpdateLock".
31      */

32     public static final String JavaDoc USE_UPDATE_LOCK_PROPERTY = "com.triactive.jdo.useUpdateLock";
33
34     private static final Category LOG = Category.getInstance(NonmanagedTransaction.class);
35     private static boolean useUpdateLockProperty = Boolean.getBoolean(USE_UPDATE_LOCK_PROPERTY);
36
37     private final PersistenceManagerImpl pm;
38     private final DatabaseAdapter dba;
39     private final DataSource JavaDoc tds;
40     private final DataSource JavaDoc ntds;
41     private final String JavaDoc userName;
42     private final String JavaDoc password;
43
44     private boolean retainValues;
45     private boolean restoreValues;
46     private boolean optimistic;
47     private boolean nontransactionalRead;
48     private boolean nontransactionalWrite;
49     private int isolationLevel;
50     private boolean useUpdateLock;
51
52     private Synchronization JavaDoc sync = null;
53     private Connection JavaDoc conn = null;
54     private boolean active = false;
55     private boolean completing = false;
56
57     public NonmanagedTransaction(PersistenceManagerImpl pm, String JavaDoc userName, String JavaDoc password)
58     {
59         this.pm = pm;
60         this.dba = pm.getStoreManager().getDatabaseAdapter();
61
62         PersistenceManagerFactoryImpl pmf = (PersistenceManagerFactoryImpl)pm.getPersistenceManagerFactory();
63
64         this.tds = pmf.getTransactionalDataSource();
65         this.ntds = pmf.getNontransactionalDataSource();
66         this.userName = userName;
67         this.password = password;
68
69         setRetainValues(pmf.getRetainValues());
70         setRestoreValues(pmf.getRestoreValues());
71         setOptimistic(pmf.getOptimistic());
72         setNontransactionalRead(pmf.getNontransactionalRead());
73         setNontransactionalWrite(pmf.getNontransactionalWrite());
74         setTransactionIsolation(pmf.getTransactionIsolation());
75     }
76
77     public PersistenceManager getPersistenceManager()
78     {
79         return pm;
80     }
81
82
83     public synchronized Connection JavaDoc getConnection(boolean forWriting) throws SQLException JavaDoc
84     {
85         if (active)
86         {
87             /*
88              * Before performing any (more) SQL operations in this transaction,
89              * flush out any updates pending in the persistence manager.
90              */

91             pm.flushDirty();
92         }
93         else
94         {
95             if (!nontransactionalRead || (forWriting && !nontransactionalWrite))
96                 throw new TransactionNotActiveException();
97
98             if (conn != null)
99                 throw new ConnectionInUseException();
100
101             conn = dba.getConnection(ntds, userName, password, Connection.TRANSACTION_NONE);
102         }
103
104         return conn;
105     }
106
107
108     public synchronized void releaseConnection(Connection JavaDoc conn) throws SQLException JavaDoc
109     {
110         if (conn == this.conn)
111         {
112             if (!active)
113                 closeConnection();
114         }
115     }
116
117
118     public boolean useUpdateLockOnFetch()
119     {
120         return active ? useUpdateLock : false;
121     }
122
123
124     private void closeConnection() throws SQLException JavaDoc
125     {
126         try
127         {
128             dba.closeConnection(conn);
129         }
130         finally
131         {
132             conn = null;
133         }
134     }
135
136
137     private void assertNotInUse()
138     {
139         if (active)
140             throw new TransactionActiveException();
141
142         if (conn != null)
143             throw new ConnectionInUseException();
144     }
145
146
147     private void assertNotCompleting()
148     {
149         if (completing)
150             throw new TransactionCompletionException();
151     }
152
153
154     private void assertCanComplete()
155     {
156         assertNotCompleting();
157
158         if (!active)
159             throw new TransactionNotActiveException();
160     }
161
162
163     public synchronized void begin()
164     {
165         assertNotInUse();
166
167         try
168         {
169             conn = dba.getConnection(tds, userName, password, isolationLevel);
170
171             active = true;
172
173             if (LOG.isDebugEnabled())
174                 LOG.debug("Transaction begun, connection = " + conn);
175         }
176         catch (SQLException JavaDoc e)
177         {
178             throw new JDOFatalDataStoreException("Failed beginning transaction", e);
179         }
180     }
181
182
183     public synchronized void commit()
184     {
185         assertCanComplete();
186
187         completing = true;
188
189         try
190         {
191             boolean success = false;
192
193             try
194             {
195                 try
196                 {
197                     if (LOG.isDebugEnabled())
198                         LOG.debug("Transaction committing, connection = " + conn);
199
200                     pm.flushDirty();
201
202                     if (sync != null)
203                         sync.beforeCompletion();
204
205                     conn.commit();
206
207                     success = true;
208                 }
209                 finally
210                 {
211                     if (!success)
212                     {
213                         try
214                         {
215                             pm.preRollback();
216                         }
217                         finally
218                         {
219                             conn.rollback();
220                         }
221                     }
222                 }
223             }
224             finally
225             {
226                 try
227                 {
228                     active = false;
229                     closeConnection();
230                 }
231                 finally
232                 {
233                     try
234                     {
235                         if (success)
236                             pm.postCommit();
237                     }
238                     finally
239                     {
240                         if (sync != null)
241                         {
242                             if (success)
243                                 sync.afterCompletion(Status.STATUS_COMMITTED);
244                             else
245                                 sync.afterCompletion(Status.STATUS_ROLLEDBACK);
246                         }
247                     }
248                 }
249             }
250         }
251         catch (SQLException JavaDoc e)
252         {
253             throw new JDOFatalDataStoreException("Failed committing transaction", e);
254         }
255         finally
256         {
257             completing = false;
258         }
259     }
260
261
262     public synchronized void rollback()
263     {
264         assertCanComplete();
265
266         completing = true;
267
268         try
269         {
270             try
271             {
272                 try
273                 {
274                     if (LOG.isDebugEnabled())
275                         LOG.debug("Transaction rolling back, connection = " + conn);
276
277                     pm.preRollback();
278                 }
279                 finally
280                 {
281                     conn.rollback();
282                 }
283             }
284             finally
285             {
286                 try
287                 {
288                     active = false;
289                     closeConnection();
290                 }
291                 finally
292                 {
293                     if (sync != null)
294                         sync.afterCompletion(Status.STATUS_ROLLEDBACK);
295                 }
296             }
297         }
298         catch (SQLException JavaDoc e)
299         {
300             throw new JDOFatalDataStoreException("Failed rolling back transaction", e);
301         }
302         finally
303         {
304             completing = false;
305         }
306     }
307
308
309     public boolean isActive()
310     {
311         return active;
312     }
313
314     public synchronized void setNontransactionalRead(boolean nontransactionalRead)
315     {
316         assertNotCompleting();
317
318         this.nontransactionalRead = nontransactionalRead;
319     }
320
321     public boolean getNontransactionalRead()
322     {
323         return nontransactionalRead;
324     }
325
326     public synchronized void setNontransactionalWrite(boolean nontransactionalWrite)
327     {
328         assertNotCompleting();
329
330         if (nontransactionalWrite)
331             throw new JDOUnsupportedOptionException("Non-transactional write mode not (yet) supported");
332
333         this.nontransactionalWrite = nontransactionalWrite;
334     }
335
336     public boolean getNontransactionalWrite()
337     {
338         return nontransactionalWrite;
339     }
340
341     public synchronized void setRetainValues(boolean retainValues)
342     {
343         assertNotCompleting();
344
345         this.retainValues = retainValues;
346
347         if (retainValues)
348             nontransactionalRead = true;
349     }
350
351     public boolean getRetainValues()
352     {
353         return retainValues;
354     }
355
356
357     public synchronized void setRestoreValues(boolean restoreValues)
358     {
359         assertNotInUse();
360
361         this.restoreValues = restoreValues;
362     }
363
364
365     public boolean getRestoreValues()
366     {
367         return restoreValues;
368     }
369
370
371     public synchronized void setOptimistic(boolean optimistic)
372     {
373         assertNotInUse();
374
375         if (optimistic)
376             throw new JDOUnsupportedOptionException("Optimistic mode not (yet) supported");
377
378         this.optimistic = optimistic;
379     }
380
381     public boolean getOptimistic()
382     {
383         return optimistic;
384     }
385
386     public synchronized void setTransactionIsolation(int isolationLevel)
387     {
388         assertNotInUse();
389
390         switch (isolationLevel)
391         {
392             case Connection.TRANSACTION_READ_UNCOMMITTED:
393             case Connection.TRANSACTION_READ_COMMITTED:
394                 useUpdateLock = useUpdateLockProperty;
395                 break;
396
397             case Connection.TRANSACTION_REPEATABLE_READ:
398             case Connection.TRANSACTION_SERIALIZABLE:
399                 useUpdateLock = false;
400                 break;
401
402             default:
403                 throw new IllegalArgumentException JavaDoc("Illegal isolation level: " + isolationLevel);
404         }
405
406         this.isolationLevel = isolationLevel;
407     }
408
409     public int getTransactionIsolation()
410     {
411         return isolationLevel;
412     }
413
414     public synchronized void setSynchronization(Synchronization JavaDoc sync)
415     {
416         assertNotCompleting();
417
418         this.sync = sync;
419     }
420
421     public Synchronization JavaDoc getSynchronization()
422     {
423         return sync;
424     }
425 }
426
Popular Tags