001: package demo.bank.concurrency;
002:
003: /**
004:
005: * Simple Transaction Service example, code taken and adapted
006:
007: * from http://www.wiley.com/compbooks/vogel/ejb/code.html
008:
009: */
010:
011: import org.omg.CORBA.*;
012:
013: import org.omg.CosTransactions.*;
014:
015: import org.omg.CosConcurrencyControl.*;
016:
017: import org.omg.CosConcurrencyControl.*;
018:
019: public class AccountImpl
020:
021: extends AccountPOA
022:
023: {
024:
025: private float balance;
026:
027: private float newBalance;
028:
029: private TransactionalLockSet lock_set;
030:
031: private String name;
032:
033: private int id;
034:
035: private Coordinator current_transaction = null;
036:
037: private boolean prepared = false;
038:
039: public AccountImpl(TransactionalLockSet lock_set, String name,
040: float deposit, int id)
041:
042: {
043:
044: this .name = name;
045:
046: this .lock_set = lock_set;
047:
048: this .id = id;
049:
050: balance = deposit;
051:
052: newBalance = balance;
053:
054: }
055:
056: public synchronized float get_balance(Control control) {
057:
058: try {
059:
060: Coordinator coord = control.get_coordinator();
061:
062: // If my transaction change account or nobody change account
063:
064: if (lock_set.try_lock(coord, lock_mode.read)) {
065:
066: float r = newBalance;
067:
068: lock_set.unlock(coord, lock_mode.read);
069:
070: return r;
071:
072: } else {
073:
074: // Anybody change account get_last valid data
075:
076: return balance;
077:
078: }
079:
080: } catch (Exception e) {
081:
082: e.printStackTrace();
083:
084: throw new org.omg.CORBA.INTERNAL();
085:
086: }
087:
088: }
089:
090: public synchronized void debit(float amount, Control control)
091:
092: throws InsufficientFunds
093:
094: {
095:
096: try
097:
098: {
099:
100: Coordinator coord = control.get_coordinator();
101:
102: // lock account for write
103:
104: while (!lock_set.try_lock(coord, lock_mode.write)) {
105:
106: try {
107:
108: wait();
109:
110: } catch (Exception e) {
111:
112: e.printStackTrace();
113:
114: }
115:
116: }
117:
118: // check founds
119:
120: if (amount > newBalance) {
121:
122: lock_set.unlock(coord, lock_mode.write);
123:
124: System.out.println("Resource: " + name
125: + " account unlocked");
126:
127: throw new InsufficientFunds();
128:
129: }
130:
131: newBalance -= amount;
132:
133: if (current_transaction == null) {
134:
135: current_transaction = coord;
136:
137: coord.register_resource(_this ());
138:
139: }
140: ;
141:
142: } catch (Unavailable u) {
143:
144: System.err.println("Account " + name
145: + "::debit: exception: " + u);
146:
147: } catch (LockNotHeld h) {
148:
149: System.err.println("Account " + name
150: + "::debit: exception: " + h);
151:
152: } catch (Inactive i) {
153:
154: System.err.println("Account " + name
155: + "::debit: exception: " + i);
156:
157: } catch (SystemException se) {
158:
159: System.err.println("Account " + name
160: + "::debit: exception: " + se);
161:
162: }
163: ;
164:
165: }
166:
167: public synchronized void credit(float amount, Control control)
168:
169: {
170:
171: try
172:
173: {
174:
175: Coordinator coord = control.get_coordinator();
176:
177: // lock account for write
178:
179: while (!lock_set.try_lock(coord, lock_mode.write)) {
180:
181: try {
182:
183: wait();
184:
185: } catch (Exception e) {
186:
187: e.printStackTrace();
188:
189: }
190:
191: }
192:
193: newBalance += amount;
194:
195: if (current_transaction == null) {
196:
197: current_transaction = coord;
198:
199: coord.register_resource(_this ());
200:
201: }
202: ;
203:
204: }
205:
206: catch (Unavailable u) {
207:
208: System.err.println("Account " + name
209: + "::credit: exception: " + u);
210:
211: }
212:
213: catch (Inactive i) {
214:
215: System.err.println("Account " + name
216: + "::credit: exception: " + i);
217:
218: }
219:
220: catch (SystemException se) {
221:
222: System.err.println("Account " + name
223: + "::credit: exception: " + se);
224:
225: }
226:
227: }
228:
229: public TransactionalLockSet get_lock_set() {
230:
231: return lock_set;
232:
233: };
234:
235: public java.lang.String owner() {
236:
237: return name;
238:
239: };
240:
241: public int account_code() {
242:
243: return id;
244:
245: };
246:
247: // implement methods of the Resource interface
248:
249: public synchronized Vote prepare()
250:
251: {
252:
253: if (balance == newBalance)
254:
255: return Vote.VoteReadOnly;
256:
257: return Vote.VoteCommit;
258:
259: }
260:
261: public synchronized void rollback() {
262:
263: newBalance = balance;
264:
265: current_transaction = null;
266:
267: notifyAll();
268:
269: }
270:
271: public synchronized void commit() {
272:
273: balance = newBalance;
274:
275: current_transaction = null;
276:
277: notifyAll();
278:
279: }
280:
281: public synchronized void commit_one_phase()
282:
283: {
284:
285: if (prepare() == Vote.VoteCommit) {
286:
287: commit();
288:
289: }
290:
291: }
292:
293: public synchronized void forget()
294:
295: {
296:
297: System.out.println("Resource " + name + " : forget()");
298:
299: }
300:
301: }
|