package org.jacorb.demo.bank.concurrency;
/**
* Simple Transaction Service example, code taken and adapted
* from http://www.wiley.com/compbooks/vogel/ejb/code.html
*/
import org.omg.CORBA.*;
import org.omg.CosTransactions.*;
import org.omg.CosConcurrencyControl.*;
import org.omg.CosConcurrencyControl.*;
public class AccountImpl
extends AccountPOA
{
private float balance;
private float newBalance;
private TransactionalLockSet lock_set;
private String name;
private int id;
private Coordinator current_transaction = null;
private boolean prepared = false;
public AccountImpl( TransactionalLockSet lock_set, String name, float deposit, int id )
{
this.name = name;
this.lock_set = lock_set;
this.id = id;
balance = deposit;
newBalance = balance;
}
public synchronized float get_balance( Control control ){
try {
Coordinator coord = control.get_coordinator();
// If my transaction change account or nobody change account
if( lock_set.try_lock( coord, lock_mode.read ) ) {
float r = newBalance;
lock_set.unlock( coord, lock_mode.read );
return r;
} else {
// Anybody change account get_last valid data
return balance;
}
} catch ( Exception e ) {
e.printStackTrace();
throw new org.omg.CORBA.INTERNAL();
}
}
public synchronized void debit( float amount, Control control )
throws InsufficientFunds
{
try
{
Coordinator coord = control.get_coordinator();
// lock account for write
while( ! lock_set.try_lock( coord, lock_mode.write ) ){
try {
wait();
} catch ( Exception e ){
e.printStackTrace();
}
}
// check founds
if( amount > newBalance ) {
lock_set.unlock( coord, lock_mode.write );
System.out.println("Resource: " + name + " account unlocked");
throw new InsufficientFunds();
}
newBalance -= amount;
if( current_transaction == null ){
current_transaction = coord;
coord.register_resource( _this() );
};
} catch( Unavailable u ) {
System.err.println("Account " + name + "::debit: exception: " + u );
} catch( LockNotHeld h ) {
System.err.println("Account " + name + "::debit: exception: " + h );
} catch( Inactive i ) {
System.err.println("Account " + name + "::debit: exception: " + i );
} catch( SystemException se ) {
System.err.println("Account " + name + "::debit: exception: " + se );
};
}
public synchronized void credit( float amount, Control control )
{
try
{
Coordinator coord = control.get_coordinator();
// lock account for write
while( ! lock_set.try_lock( coord, lock_mode.write ) ){
try {
wait();
} catch ( Exception e ){
e.printStackTrace();
}
}
newBalance += amount;
if( current_transaction == null ){
current_transaction = coord;
coord.register_resource( _this() );
};
}
catch( Unavailable u ) {
System.err.println("Account " + name + "::credit: exception: " + u );
}
catch( Inactive i ) {
System.err.println("Account " + name + "::credit: exception: " + i );
}
catch( SystemException se ) {
System.err.println("Account " + name + "::credit: exception: " + se );
}
}
public TransactionalLockSet get_lock_set(){
return lock_set;
};
public java.lang.String owner(){
return name;
};
public int account_code(){
return id;
};
// implement methods of the Resource interface
public synchronized Vote prepare()
{
if( balance == newBalance )
return Vote.VoteReadOnly;
return Vote.VoteCommit;
}
public synchronized void rollback() {
newBalance = balance;
current_transaction = null;
notifyAll();
}
public synchronized void commit() {
balance = newBalance;
current_transaction = null;
notifyAll();
}
public synchronized void commit_one_phase()
{
if(prepare() == Vote.VoteCommit) {
commit();
}
}
public synchronized void forget()
{
System.out.println("Resource " + name + " : forget()");
}
}