X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.cms%2Fsrc%2Forg%2Fargeo%2Fapi%2Fcms%2Ftransaction%2FSimpleTransactionManager.java;fp=org.argeo.api.cms%2Fsrc%2Forg%2Fargeo%2Fapi%2Fcms%2Ftransaction%2FSimpleTransactionManager.java;h=ee99ccb1962dee20e72084275775cf3df8d3c171;hb=54df376a9c2dd458a82eaa09bfbb718fe699dd0d;hp=0000000000000000000000000000000000000000;hpb=3c1cdc594d954520b14646102b366290bdad58c7;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/transaction/SimpleTransactionManager.java b/org.argeo.api.cms/src/org/argeo/api/cms/transaction/SimpleTransactionManager.java new file mode 100644 index 000000000..ee99ccb19 --- /dev/null +++ b/org.argeo.api.cms/src/org/argeo/api/cms/transaction/SimpleTransactionManager.java @@ -0,0 +1,214 @@ +package org.argeo.api.cms.transaction; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; + +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +/** + * Simple implementation of an XA transaction manager. + */ +public class SimpleTransactionManager +// implements TransactionManager, UserTransaction + implements WorkControl, WorkTransaction { + private ThreadLocal> current = new ThreadLocal>(); + + private Map> knownTransactions = Collections + .synchronizedMap(new HashMap>()); + private TransactionStatusAdapter tsa = new JtaStatusAdapter(); +// private SyncRegistry syncRegistry = new SyncRegistry(); + + /* + * WORK IMPLEMENTATION + */ + @Override + public T required(Callable work) { + T res; + begin(); + try { + res = work.call(); + commit(); + } catch (Exception e) { + rollback(); + throw new SimpleRollbackException(e); + } + return res; + } + + @Override + public WorkContext getWorkContext() { + return new WorkContext() { + + @Override + public void registerXAResource(XAResource resource, String recoveryId) { + getTransaction().enlistResource(resource); + } + }; + } + + /* + * WORK TRANSACTION IMPLEMENTATION + */ + + @Override + public boolean isNoTransactionStatus() { + return tsa.getNoTransactionStatus().equals(getStatus()); + } + + /* + * JTA IMPLEMENTATION + */ + + public void begin() +// throws NotSupportedException, SystemException + { + if (getCurrent() != null) + throw new UnsupportedOperationException("Nested transactions are not supported"); + SimpleTransaction transaction = new SimpleTransaction(this, tsa); + knownTransactions.put(transaction.getXid(), transaction); + current.set(transaction); + } + + public void commit() +// throws RollbackException, HeuristicMixedException, HeuristicRollbackException, +// SecurityException, IllegalStateException, SystemException + { + if (getCurrent() == null) + throw new IllegalStateException("No transaction registered with the current thread."); + getCurrent().commit(); + } + + public int getStatus() +// throws SystemException + { + if (getCurrent() == null) + return tsa.getNoTransactionStatus(); + return getTransaction().getStatus(); + } + + public SimpleTransaction getTransaction() +// throws SystemException + { + return getCurrent(); + } + + protected SimpleTransaction getCurrent() +// throws SystemException + { + SimpleTransaction transaction = current.get(); + if (transaction == null) + return null; + Integer status = transaction.getStatus(); + if (status.equals(tsa.getCommittedStatus()) || status.equals(tsa.getRolledBackStatus())) { + current.remove(); + return null; + } + return transaction; + } + + void unregister(Xid xid) { + knownTransactions.remove(xid); + } + + public void resume(SimpleTransaction tobj) +// throws InvalidTransactionException, IllegalStateException, SystemException + { + if (getCurrent() != null) + throw new IllegalStateException("Transaction " + current.get() + " already registered"); + current.set(tobj); + } + + public void rollback() +// throws IllegalStateException, SecurityException, SystemException + { + if (getCurrent() == null) + throw new IllegalStateException("No transaction registered with the current thread."); + getCurrent().rollback(); + } + + public void setRollbackOnly() +// throws IllegalStateException, SystemException + { + if (getCurrent() == null) + throw new IllegalStateException("No transaction registered with the current thread."); + getCurrent().setRollbackOnly(); + } + + public void setTransactionTimeout(int seconds) +// throws SystemException + { + throw new UnsupportedOperationException(); + } + + public SimpleTransaction suspend() +// throws SystemException + { + SimpleTransaction transaction = getCurrent(); + current.remove(); + return transaction; + } + +// public TransactionSynchronizationRegistry getTsr() { +// return syncRegistry; +// } +// +// private class SyncRegistry implements TransactionSynchronizationRegistry { +// @Override +// public Object getTransactionKey() { +// try { +// SimpleTransaction transaction = getCurrent(); +// if (transaction == null) +// return null; +// return getCurrent().getXid(); +// } catch (SystemException e) { +// throw new IllegalStateException("Cannot get transaction key", e); +// } +// } +// +// @Override +// public void putResource(Object key, Object value) { +// throw new UnsupportedOperationException(); +// } +// +// @Override +// public Object getResource(Object key) { +// throw new UnsupportedOperationException(); +// } +// +// @Override +// public void registerInterposedSynchronization(Synchronization sync) { +// throw new UnsupportedOperationException(); +// } +// +// @Override +// public int getTransactionStatus() { +// try { +// return getStatus(); +// } catch (SystemException e) { +// throw new IllegalStateException("Cannot get status", e); +// } +// } +// +// @Override +// public boolean getRollbackOnly() { +// try { +// return getStatus() == Status.STATUS_MARKED_ROLLBACK; +// } catch (SystemException e) { +// throw new IllegalStateException("Cannot get status", e); +// } +// } +// +// @Override +// public void setRollbackOnly() { +// try { +// getCurrent().setRollbackOnly(); +// } catch (Exception e) { +// throw new IllegalStateException("Cannot set rollback only", e); +// } +// } +// +// } +}