comparison src/org/dancres/blitz/disk/DiskTxn.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.disk;
2
3 import java.io.IOException;
4
5 import java.util.Stack;
6 import java.util.logging.Level;
7
8 import com.sleepycat.je.Transaction;
9 import com.sleepycat.je.DatabaseException;
10 import com.sleepycat.je.Database;
11
12 import EDU.oswego.cs.dl.util.concurrent.LockReleaser;
13
14 /**
15 Disk operations are encapsulated in transactions for the purposes of
16 recovery etc. DiskTxn represents such transactions. No DiskTxn means
17 no disk update.
18 */
19 public class DiskTxn {
20 private static ThreadLocal ACTIVE_TXN = new ThreadLocal();
21
22 private Transaction theTxn;
23
24 private boolean amStandalone = false;
25
26 private DiskTxn(Transaction aTxn) {
27 theTxn = aTxn;
28 }
29
30 private DiskTxn(Transaction aTxn, boolean isStandalone) {
31 theTxn = aTxn;
32 amStandalone = isStandalone;
33 }
34
35 /**
36 Create a new txn and make it part of the current thread's context.
37 <B>Warning</B> if there's another Txn already associated with this
38 thread (i.e. a non-standalone txn) then it will be overwritten by
39 this one with the resultant loss of the old transaction which will
40 remain open forever - this would be bad! Under circumstances where
41 it's necessary to nest txns, use newStandlone().
42 */
43 public static DiskTxn newTxn() throws IOException {
44 Transaction myDbTxn;
45
46 try {
47 myDbTxn = Disk.newTxn();
48 } catch (DatabaseException aDbe) {
49 Disk.theLogger.log(Level.SEVERE, "Got DatabaseException", aDbe);
50 throw new IOException("DatabaseException");
51 }
52
53 DiskTxn myTxn = new DiskTxn(myDbTxn);
54
55 ACTIVE_TXN.set(myTxn);
56
57 return myTxn;
58 }
59
60 /**
61 Create a new txn but don't make it a part of the current thread's
62 context.
63 */
64 public static DiskTxn newStandalone() throws IOException {
65 Transaction myDbTxn;
66
67 try {
68 myDbTxn = Disk.newTxn();
69 } catch (DatabaseException aDbe) {
70 Disk.theLogger.log(Level.SEVERE, "Got DatabaseException", aDbe);
71 throw new IOException("DatabaseException");
72 }
73
74 DiskTxn myTxn = new DiskTxn(myDbTxn, true);
75
76 return myTxn;
77 }
78
79 /**
80 If you choose to use a non-blocking transaction, you must be prepared
81 to handle (for Db) <code>DatabaseException</code> with an errno of
82 <code>Db.DB_LOCK_NOTGRANTED</code> during any operations performed under
83 that transaction. This breaks encapsulation of Db a little.
84 Note that Db documentation for 4.1.25 would lead a programmer to
85 believe they need to handle DbLockNotGrantedException - unfortunately,
86 that never seems to be thrown - sigh.
87
88 @todo Fix API leakage.
89 */
90 public static DiskTxn newNonBlockingStandalone() throws IOException {
91 Transaction myDbTxn;
92
93 try {
94 myDbTxn = Disk.newNonBlockingTxn();
95 } catch (DatabaseException aDbe) {
96 Disk.theLogger.log(Level.SEVERE, "Got DatabaseException", aDbe);
97 throw new IOException("DatabaseException");
98 }
99
100 DiskTxn myTxn = new DiskTxn(myDbTxn, true);
101
102 return myTxn;
103 }
104
105 public static DiskTxn getActiveTxn() {
106 return (DiskTxn) ACTIVE_TXN.get();
107 }
108
109 public static Transaction getActiveDbTxn() {
110 return getActiveTxn().getDbTxn();
111 }
112
113 public Transaction getDbTxn() {
114 return theTxn;
115 }
116
117 /**
118 Commit the transaction with no forced logging. If you want forced
119 logging invoke <code>commit(true)</code>.
120 */
121 public void commit() throws IOException {
122 commit(false);
123 }
124
125 public void commit(boolean shouldSync) throws IOException {
126 try {
127 if (shouldSync)
128 theTxn.commitSync();
129 else
130 theTxn.commitNoSync();
131 } catch (DatabaseException aDbe) {
132 Disk.theLogger.log(Level.SEVERE, "Got DatabaseException", aDbe);
133 throw new IOException("DatabaseException");
134 }
135
136 release();
137
138 if (!amStandalone)
139 ACTIVE_TXN.set(null);
140 }
141
142 public void abort() throws IOException {
143 try {
144 theTxn.abort();
145 } catch (DatabaseException aDbe) {
146 Disk.theLogger.log(Level.SEVERE, "Got DatabaseException", aDbe);
147 throw new IOException("DatabaseException");
148 }
149
150 release();
151
152 if (!amStandalone)
153 ACTIVE_TXN.set(null);
154 }
155
156 private void release() {
157 }
158 }