001: package demo.bank.transaction.implicit;
002:
003: /**
004: * Simple Transaction Service example, code taken and adapted
005: * from http://www.wiley.com/compbooks/vogel/ejb/code.html
006: */
007:
008: import org.omg.CORBA.*;
009: import org.omg.CosTransactions.*;
010:
011: public class AccountImpl extends AccountPOA {
012: private float balance;
013: private float newBalance;
014: private float amount;
015: private boolean credit;
016: private ORB orb;
017: private String name;
018: private Lock lock;
019:
020: private boolean nasty = false;
021: private int nasty_count = 0;
022:
023: public AccountImpl(ORB orb, String name, float deposit) {
024: this (orb, name, deposit, false);
025: }
026:
027: public AccountImpl(ORB orb, String name, float deposit,
028: boolean nasty) {
029: this .name = name;
030: this .orb = orb;
031: this .nasty = nasty;
032:
033: balance = deposit;
034: lock = new Lock();
035: }
036:
037: public float balance() {
038: return balance;
039: }
040:
041: public synchronized void credit(float amount) {
042: try {
043: if (nasty) {
044: switch (nasty_count++) {
045: case 0:
046: break;
047: case 1:
048: System.out.println("Step 1 nastyness: error");
049: throw new Error("Bank Holidays");
050: case 2:
051: System.out
052: .println("Step 2 nastyness: COMM_FALIURE");
053: throw new org.omg.CORBA.COMM_FAILURE();
054: }
055: }
056:
057: // lock account
058: lock.lock();
059:
060: Control control = org.omg.CosTransactions.CurrentHelper
061: .narrow(
062: orb
063: .resolve_initial_references("TransactionCurrent"))
064: .get_control();
065:
066: // memorize current activitity
067: this .amount = amount;
068: credit = true;
069:
070: System.err.println("Account " + name
071: + "::credit: get coordinator");
072: Coordinator coordinator = control.get_coordinator();
073:
074: // register resource
075: System.out.println("Account " + name
076: + "::credit: register resource (Account) with ITS");
077: RecoveryCoordinator recCoordinator = coordinator
078: .register_resource(_this ());
079:
080: newBalance = balance + amount;
081: System.out.println(" credit $" + amount);
082: System.out.println(" new balance is $" + newBalance);
083: } catch (Exception ex) {
084: System.err.println("Account " + name
085: + "::credit: exception: " + ex);
086: throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK();
087: }
088: ;
089: }
090:
091: public synchronized void debit(float amount)
092: throws InsufficientFunds {
093: try {
094:
095: if (nasty) {
096: switch (nasty_count++) {
097: case 0:
098: System.out
099: .println("Step 0 nastyness: InsufficientFunds");
100: throw new InsufficientFunds();
101: case 1:
102: System.out.println("Step 1 nastyness: error");
103: throw new Error("Bank Holidays");
104: case 2:
105: System.out
106: .println("Step 2 nastyness: COMM_FALIURE");
107: throw new org.omg.CORBA.COMM_FAILURE();
108: }
109: }
110: // lock account
111: lock.lock();
112:
113: Control control = org.omg.CosTransactions.CurrentHelper
114: .narrow(
115: orb
116: .resolve_initial_references("TransactionCurrent"))
117: .get_control();
118:
119: // memorize current activitity
120: this .amount = amount;
121: credit = false;
122:
123: System.err.println("Account " + name
124: + "::debit: get coordinator");
125: Coordinator coordinator = control.get_coordinator();
126:
127: // register resource
128: System.out.println("Account " + name
129: + "::debit: register resource (Account) with ITS");
130: RecoveryCoordinator recCoordinator = coordinator
131: .register_resource(_this ());
132: System.out.println("Account " + name
133: + "::debit: resource registered");
134:
135: if (amount > balance) {
136: System.out.println("no sufficient funds");
137: lock.unlock();
138: System.out.println("Resource: " + name
139: + " account unlocked");
140: throw new InsufficientFunds();
141: }
142: newBalance = balance - amount;
143: System.out.println(" debit $" + amount);
144: System.out.println(" new balance is $" + newBalance);
145:
146: } catch (org.omg.CORBA.ORBPackage.InvalidName in) {
147: System.err.println("Account " + name
148: + "::debit: exception: " + in);
149: throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK();
150: } catch (Unavailable u) {
151: System.err.println("Account " + name
152: + "::debit: exception: " + u);
153: throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK();
154: } catch (Inactive i) {
155: System.err.println("Account " + name
156: + "::debit: exception: " + i);
157: throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK();
158: } catch (SystemException se) {
159: System.err.println("Account " + name
160: + "::debit: exception: " + se);
161: throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK();
162: }
163: }
164:
165: // implement methods of the Resource interface
166:
167: public Vote prepare() {
168: System.out.println("Resource " + name + " : prepare()");
169: if (balance == newBalance)
170: return Vote.VoteReadOnly;
171: return Vote.VoteCommit;
172: }
173:
174: public void rollback() {
175: // remove data from temporary storage
176: System.out.println("Resource " + name + " : rollback()");
177: System.out.println("Resource " + name
178: + " : original balance restored: $" + balance);
179: lock.unlock();
180: System.out.println("Resource " + name + " account unlocked");
181: }
182:
183: public void commit() {
184: // move data to final storage
185: System.out.println("Resource " + name + " : commit()");
186: balance = newBalance;
187: lock.unlock();
188: System.out.println("Resource " + name + " account unlocked");
189: }
190:
191: public void commit_one_phase() {
192: // store data immediately at final destination
193: System.out
194: .println("Resource " + name + " : commit_one_phase()");
195: if (prepare() == Vote.VoteCommit) {
196: commit();
197: }
198: }
199:
200: public void forget() {
201: System.out.println("Resource " + name + " : forget()");
202: }
203:
204: }
|