Last two classes
Code:
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionException;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Collection;
import java.util.Collections;
/**
* The group transaction status.
*
* @author Charles Canning
*/
public class GroupTransactionStatus implements TransactionStatus {
/**
* The map of transaction statuses keyed by transaction manager name.
*/
private Map<String, TransactionStatus> transactions;
/**
* The group save point.
*/
private GroupSavepoint savepoint;
public GroupTransactionStatus(Map<String, TransactionStatus> transactions) {
this.transactions = transactions;
}
/**
* This will determine if the transaction is new.
*
* @return true if new, false otherwise
* @TODO should we make a check to see if they are out of sync? do we support this or not??
*/
public boolean isNewTransaction() {
boolean isNewTransaction = true;
//step through the transactions and AND the is new flag
for (TransactionStatus transaction : getTransactions()) {
isNewTransaction &= transaction.isNewTransaction();
}
return isNewTransaction;
}
/**
* This will set the rollback only flag for all transactions in the group.
*/
public void setRollbackOnly() {
//step through the transactions and set roolback only
for (TransactionStatus transaction : getTransactions()) {
transaction.setRollbackOnly();
}
}
public boolean isRollbackOnly() {
boolean isRollbackOnly = true;
//step through the transactions and OR the is new flag
for (TransactionStatus transaction : getTransactions()) {
isRollbackOnly &= transaction.isRollbackOnly();
}
return isRollbackOnly;
}
public boolean isCompleted() {
boolean isCompleted = true;
//step through the transactions and OR the is new flag
for (TransactionStatus transaction : getTransactions()) {
isCompleted &= transaction.isCompleted();
}
return isCompleted;
}
public boolean hasSavepoint() {
return savepoint != null;
}
public Object createSavepoint() throws TransactionException {
Map<String, Object> savepoints;
TransactionStatus transaction;
//create the savepoints and add each to the map keyed by transaction
savepoints = new LinkedHashMap<String, Object>();
//step through the transaction keys
for (String transactionKey : getTransactionKeys()) {
//get the transaction
transaction = transactions.get(transactionKey);
//create the save point and add to map of savepoints
savepoints.put(transactionKey, transaction.createSavepoint());
}
//create the savepoint and return it
savepoint = new GroupSavepoint(savepoints);
return savepoint;
}
public void rollbackToSavepoint(Object savepoint) throws TransactionException {
rollbackToSavepoint((GroupSavepoint) savepoint);
}
public void rollbackToSavepoint(GroupSavepoint savepoint) throws TransactionException {
TransactionStatus transaction;
Object transactionSavepoint;
//step through each transaction and rollback to its savepoint
for (String transactionKey : getTransactionKeys()) {
//get the transaction
transaction = transactions.get(transactionKey);
//get the transaction savepoint
transactionSavepoint = savepoint.getTransactionSavepoint(transactionKey);
//rollback the transaction to the save point
transaction.rollbackToSavepoint(transactionSavepoint);
}
}
public void releaseSavepoint(Object savepoint) throws TransactionException {
releaseSavepoint((GroupSavepoint) savepoint);
}
public void releaseSavepoint(GroupSavepoint savepoint) throws TransactionException {
TransactionStatus transaction;
Object transactionSavepoint;
//step through each transaction and rollback to its savepoint
for (String transactionKey : getTransactionKeys()) {
//get the transaction
transaction = transactions.get(transactionKey);
//get the transaction savepoint
transactionSavepoint = savepoint.getTransactionSavepoint(transactionKey);
//release the transaction to the save point
transaction.releaseSavepoint(transactionSavepoint);
}
}
/**
* @return the collection of transaction keys
*/
protected Collection<String> getTransactionKeys() {
return transactions.keySet();
}
/**
* This will get the specified transaction.
* @param transactionKey - the transaction key
* @return the collection of transaction statuses
*/
protected TransactionStatus getTransaction(String transactionKey) {
return transactions.get(transactionKey);
}
/**
* @return the collection of transaction statuses
*/
protected Collection<TransactionStatus> getTransactions() {
return transactions.values();
}
/**
* This is the group save point if save points are supported. The group savepoint is an immutable object.
*
* @author Charles Canning
*/
class GroupSavepoint {
/**
* The map of save points keyed by transaction manager name.
*/
private Map<String, Object> savepoints;
/**
* This will create the group savepoint with all the individual transaction savepoints.
*
* @param savepoints - the map of savepoints keyed by transaction manager
*/
GroupSavepoint(Map<String, Object> savepoints) {
this.savepoints = savepoints;
}
/**
* @param transactionKey - the transaction key
* @return the savepoint for the specified transaction
*/
public Object getTransactionSavepoint(String transactionKey) {
return savepoints.get(transactionKey);
}
/**
* @return the unmodifiable collection of transaction keys.
*/
public Collection<String> getTransactionKeys() {
return Collections.unmodifiableSet(savepoints.keySet());
}
/**
* @return the unmodifiable collection of savepoints.
*/
public Collection<Object> getSavepoints() {
return Collections.unmodifiableCollection(savepoints.values());
}
}
}
Code:
import org.springframework.transaction.TransactionException;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Collection;
/**
* The group transaction exception will contain the exceptions for each transaction keyed by transaction key.
* @author Charles Canning
*/
public class GroupTransactionException extends TransactionException {
/**
* The map of exceptions.
*/
private Map<String, Exception> exceptions;
public GroupTransactionException(String msg) {
super(msg);
//create the map.
exceptions = new LinkedHashMap<String, Exception>();
}
/**
* This will put the exception keyed by transaction key.
* @param transactionKey - the transaction key
* @param exception - the exception that occurred with the named transaction
*/
public void put(String transactionKey, Exception exception) {
exceptions.put(transactionKey, exception);
}
public Exception get(String transactionKey) {
return exceptions.get(transactionKey);
}
public int size() {
return exceptions.size();
}
public Collection<String> getTransactionKeys() {
return exceptions.keySet();
}
public Collection<Exception> getExceptions() {
return exceptions.values();
}
}