ManagedTransaction.java
package doss.core;
import java.io.IOException;
/**
* A transaction with a managed lifecycle.
*/
public abstract class ManagedTransaction implements Transaction {
protected State state = State.OPEN;
abstract protected Transaction getCallbacks();
@Override
public synchronized void close() throws IllegalStateException, IOException {
state = state.close(getCallbacks());
}
@Override
public synchronized void commit() throws IllegalStateException, IOException {
state = state.commit(getCallbacks());
}
@Override
public synchronized void rollback() throws IllegalStateException,
IOException {
state = state.rollback(getCallbacks());
}
@Override
public synchronized void prepare() throws IllegalStateException,
IOException {
state = state.prepare(getCallbacks());
}
/**
* Transaction state machine.
*
* Defines valid state transitions for a {@link Transaction} and manages an
* instance through those states. Passes all exceptions from the managed
* transaction through to the caller.
*/
protected static enum State {
OPEN {
@Override
public State close(Transaction t) throws IllegalStateException,
IOException {
rollback(t);
return assertPreparedCommittedOrRolledback();
}
@Override
public State prepare(Transaction t) throws IOException {
t.prepare();
return PREPARED;
}
@Override
public State commit(Transaction t) throws IOException {
return prepare(t).commit(t);
}
@Override
public State rollback(Transaction t) throws IOException {
t.rollback();
return ROLLEDBACK;
}
@Override
public State assertOpen() {
return this;
}
@Override
public State assertOpenOrPrepared() {
return this;
}
},
PREPARED {
@Override
public State commit(Transaction t) throws IOException {
t.commit();
return COMMITTED;
}
@Override
public State rollback(Transaction t) throws IOException {
t.rollback();
return ROLLEDBACK;
}
@Override
public State assertOpenOrPrepared() {
return this;
}
},
COMMITTED, ROLLEDBACK;
// defaults
public State close(Transaction t) throws IOException {
t.close();
return this;
}
public State prepare(Transaction t) throws IOException {
return assertOpen();
}
public State commit(Transaction t) throws IOException {
return assertOpenOrPrepared();
}
public State rollback(Transaction t) throws IOException {
return assertOpenOrPrepared();
}
// helpers
public State assertOpen() {
throw new IllegalStateException(name() + "; must be OPEN");
}
public State assertOpenOrPrepared() {
throw new IllegalStateException(name()
+ "; must be OPEN or PREPARED");
}
public State assertPreparedCommittedOrRolledback() {
throw new IllegalStateException(name()
+ "; must be PREPARED, COMMITTED or ROLLEDBACK");
}
}
}