KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > odmg > OzoneODMGTransaction


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Library License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id: OzoneODMGTransaction.java,v 1.1 2001/12/18 10:31:31 per_nyfelt Exp $
8

9 package org.ozoneDB.odmg;
10
11 import org.odmg.*;
12 import org.ozoneDB.*;
13 import org.ozoneDB.DxLib.*;
14
15
16 /**
17  * Implementation of the ODMG {@link Transaction} interface. A transaction works
18  * against all databases that are known by the <code>OzoneODMG</odmg> factory
19  * object when this transaction is created.
20  *
21  *
22  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
23  * @version $Revision: 1.1 $Date: 2001/12/18 10:31:31 $
24  * @see org.odmg.Transaction
25  */

26 public final class OzoneODMGTransaction implements Transaction {
27     
28     /**
29      * Holds the ExternalTransaction objects that this ODMG transaction has
30      * to handle.
31      */

32     private ExternalTransaction[] subTxs;
33     
34     /**
35      * Maps Threads into OzoneODMGTransaction.
36      */

37     private static DxMap txTable = new DxHashMap();
38     
39     
40     protected static OzoneODMGTransaction current() {
41         return (OzoneODMGTransaction)txTable.elementForKey( Thread.currentThread() );
42     }
43     
44     
45     /**
46      * Remove all threads that have joined the specified transaction.
47      * @param tx Transaction to remove from the global thread table.
48      */

49     protected static void remove( OzoneODMGTransaction tx ) {
50         DxIterator it = txTable.iterator();
51         while (it.next() != null) {
52             OzoneODMGTransaction cursor = (OzoneODMGTransaction)it.object();
53             if (cursor.equals( tx )) {
54                 it.removeObject();
55             }
56         }
57     }
58     
59     
60     public OzoneODMGTransaction( DxCollection _dbs ) {
61         boolean readOnly = false;
62         
63         if (_dbs.count() == 0) {
64             throw new DatabaseClosedException( "There is no open database." );
65         }
66         
67         subTxs = new ExternalTransaction[_dbs.count()];
68         DxIterator it = _dbs.iterator();
69         for (int i = 0; it.next() != null; i++) {
70             OzoneODMGDatabase odb = (OzoneODMGDatabase)it.object();
71             subTxs[i] = odb.underlying().newTransaction();
72             
73             if (odb.mode() == org.odmg.Database.OPEN_READ_ONLY) {
74                 readOnly = true;
75             }
76         }
77         
78         // set all transactions to roll back only if one is opened in
79
// OPEN_READ_ONLY mode
80
try {
81             if (readOnly) {
82                 for (int i = 0; i < subTxs.length; i++) {
83                     subTxs[i].setRollbackOnly();
84                 }
85             }
86         } catch (Exception JavaDoc e) {
87             subTxs = null;
88             throw new ODMGRuntimeException( e.toString() );
89         }
90     }
91     
92     
93     public void begin() {
94         if (current() != null) {
95             throw new TransactionInProgressException( "Thread already joined." );
96         }
97         
98         if (subTxs == null) {
99             throw new TransactionNotInProgressException( "Transaction already ended." );
100         }
101         
102         try {
103             for (int i = 0; i < subTxs.length; i++) {
104                 subTxs[i].begin();
105             }
106             txTable.addForKey( this, Thread.currentThread() );
107         } catch (Exception JavaDoc e) {
108             subTxs = null;
109             throw new ODMGRuntimeException( e.toString() );
110         }
111     }
112     
113     
114     public void join() {
115         if (subTxs == null) {
116             throw new TransactionNotInProgressException( "Transaction already ended." );
117         }
118         
119         leave();
120         
121         if (!txTable.addForKey( this, Thread.currentThread() )) {
122             throw new ODMGRuntimeException( "Unable to join thread." );
123         }
124         
125         try {
126             for (int i = 0; i < subTxs.length; i++) {
127                 subTxs[i].join();
128             }
129         } catch (Exception JavaDoc e) {
130         }
131     }
132     
133     
134     public void leave() {
135         if (subTxs == null) {
136             throw new TransactionNotInProgressException( "Transaction already ended." );
137         }
138         
139         txTable.removeForKey( Thread.currentThread() );
140         
141         try {
142             for (int i = 0; i < subTxs.length; i++) {
143                 subTxs[i].leave();
144             }
145         } catch (Exception JavaDoc e) {
146             throw new ODMGRuntimeException( e.toString() );
147         }
148     }
149     
150     
151     public boolean isOpen() {
152         return subTxs != null;
153     }
154     
155     
156     public void commit() {
157         // ODMG 3.0 lets us commit only if the threads has joined the transaction
158
if (!this.equals( current() )) {
159             throw new TransactionNotInProgressException( "Thread has not joined the transaction." );
160         }
161         
162         if (subTxs == null) {
163             throw new TransactionNotInProgressException( "Thread already ended." );
164         }
165         
166         // make one-phase commit if there is only one sub-transaction
167
if (subTxs.length == 1) {
168             try {
169                 subTxs[0].commit( true );
170             } catch (Exception JavaDoc e) {
171                 // if something was wrong the transaction is rolled back
172
// ODMG does not specify which exception to throw, so...
173
throw new ODMGRuntimeException( e.toString() );
174             } finally {
175                 subTxs = null;
176                 remove( this );
177             }
178         } else {
179             try {
180                 for (int i = 0; i < subTxs.length; i++) {
181                     subTxs[i].prepare();
182                 }
183                 
184                 for (int i = 0; i < subTxs.length; i++) {
185                     subTxs[i].commit( false );
186                 }
187             } catch (Exception JavaDoc e) {
188                 abort();
189                 throw new ODMGRuntimeException( e.toString() );
190             } finally {
191                 subTxs = null;
192                 remove( this );
193             }
194         }
195     }
196     
197     
198     public void abort() {
199         // ODMG 3.0 lets us commit only if the threads has joined the transaction
200
if (!this.equals( current() )) {
201             throw new TransactionNotInProgressException( "Thread has not joined the transaction." );
202         }
203         
204         // do not throw an exception to allow multiple calls of abort()
205
if (subTxs == null) {
206             return;
207         }
208         
209         try {
210             for (int i = 0; i < subTxs.length; i++) {
211                 subTxs[i].rollback();
212             }
213         } catch (Exception JavaDoc e) {
214             // we can only throw the exception here
215
throw new ODMGRuntimeException( e.toString() );
216         } finally {
217             subTxs = null;
218             remove( this );
219         }
220     }
221     
222     
223     public void checkpoint() {
224         // ODMG 3.0 lets us commit only if the threads has joined the transaction
225
if (!this.equals( current() )) {
226             throw new TransactionNotInProgressException( "Thread has not joined the transaction." );
227         }
228         
229         if (subTxs == null) {
230             throw new TransactionNotInProgressException( "Thread already ended." );
231         }
232         
233         try {
234             for (int i = 0; i < subTxs.length; i++) {
235                 subTxs[i].checkpoint();
236             }
237         } catch (Exception JavaDoc e) {
238             // Hmmm... should we abort here?
239
abort();
240             throw new ODMGRuntimeException( e.toString() );
241         }
242     }
243     
244     
245     /**
246      * Upgrade the lock on the given object to the given lock mode. The call
247      * has no effect if the object's current lock is already at or above that
248      * level of lock mode.
249      * <p>
250      * This method does nothing currently. We rely on the class descriptor for
251      * lock modes for now.
252      */

253     public void lock( Object JavaDoc obj, int lockMode ) throws LockNotGrantedException {
254     }
255     
256     
257     /**
258      * Upgrade the lock on the given object to the given lock mode.
259      * <p>
260      * This method does nothing currently. We rely on the class descriptor for
261      * lock modes for now.
262      */

263     public boolean tryLock( Object JavaDoc obj, int lockMode ) {
264         // we have to implement something here; for now rely on the class
265
// descriptor for lock modes
266
return true;
267     }
268     
269     
270     // protected void finalize throws Throwable {
271
// abort();
272
// }
273
}
274
Popular Tags