]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java
[maven-release-plugin] prepare release v2.3.4
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / transaction / simple / SimpleTransactionManager.java
1 package org.argeo.transaction.simple;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import javax.transaction.HeuristicMixedException;
8 import javax.transaction.HeuristicRollbackException;
9 import javax.transaction.InvalidTransactionException;
10 import javax.transaction.NotSupportedException;
11 import javax.transaction.RollbackException;
12 import javax.transaction.Status;
13 import javax.transaction.Synchronization;
14 import javax.transaction.SystemException;
15 import javax.transaction.Transaction;
16 import javax.transaction.TransactionManager;
17 import javax.transaction.TransactionSynchronizationRegistry;
18 import javax.transaction.UserTransaction;
19 import javax.transaction.xa.Xid;
20
21 /**
22 * Simple implementation of an XA {@link TransactionManager} and
23 * {@link UserTransaction}.
24 */
25 public class SimpleTransactionManager implements TransactionManager, UserTransaction {
26 private ThreadLocal<SimpleTransaction> current = new ThreadLocal<SimpleTransaction>();
27
28 private Map<Xid, SimpleTransaction> knownTransactions = Collections
29 .synchronizedMap(new HashMap<Xid, SimpleTransaction>());
30 private SyncRegistry syncRegistry = new SyncRegistry();
31
32 @Override
33 public void begin() throws NotSupportedException, SystemException {
34 if (getCurrent() != null)
35 throw new NotSupportedException("Nested transactions are not supported");
36 SimpleTransaction transaction = new SimpleTransaction(this);
37 knownTransactions.put(transaction.getXid(), transaction);
38 current.set(transaction);
39 }
40
41 @Override
42 public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
43 SecurityException, IllegalStateException, SystemException {
44 if (getCurrent() == null)
45 throw new IllegalStateException("No transaction registered with the current thread.");
46 getCurrent().commit();
47 }
48
49 @Override
50 public int getStatus() throws SystemException {
51 if (getCurrent() == null)
52 return Status.STATUS_NO_TRANSACTION;
53 return getTransaction().getStatus();
54 }
55
56 @Override
57 public Transaction getTransaction() throws SystemException {
58 return getCurrent();
59 }
60
61 protected SimpleTransaction getCurrent() throws SystemException {
62 SimpleTransaction transaction = current.get();
63 if (transaction == null)
64 return null;
65 int status = transaction.getStatus();
66 if (Status.STATUS_COMMITTED == status || Status.STATUS_ROLLEDBACK == status) {
67 current.remove();
68 return null;
69 }
70 return transaction;
71 }
72
73 void unregister(Xid xid) {
74 knownTransactions.remove(xid);
75 }
76
77 @Override
78 public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException {
79 if (getCurrent() != null)
80 throw new IllegalStateException("Transaction " + current.get() + " already registered");
81 current.set((SimpleTransaction) tobj);
82 }
83
84 @Override
85 public void rollback() throws IllegalStateException, SecurityException, SystemException {
86 if (getCurrent() == null)
87 throw new IllegalStateException("No transaction registered with the current thread.");
88 getCurrent().rollback();
89 }
90
91 @Override
92 public void setRollbackOnly() throws IllegalStateException, SystemException {
93 if (getCurrent() == null)
94 throw new IllegalStateException("No transaction registered with the current thread.");
95 getCurrent().setRollbackOnly();
96 }
97
98 @Override
99 public void setTransactionTimeout(int seconds) throws SystemException {
100 throw new UnsupportedOperationException();
101 }
102
103 @Override
104 public Transaction suspend() throws SystemException {
105 Transaction transaction = getCurrent();
106 current.remove();
107 return transaction;
108 }
109
110 public TransactionSynchronizationRegistry getTsr() {
111 return syncRegistry;
112 }
113
114 private class SyncRegistry implements TransactionSynchronizationRegistry {
115 @Override
116 public Object getTransactionKey() {
117 try {
118 SimpleTransaction transaction = getCurrent();
119 if (transaction == null)
120 return null;
121 return getCurrent().getXid();
122 } catch (SystemException e) {
123 throw new IllegalStateException("Cannot get transaction key", e);
124 }
125 }
126
127 @Override
128 public void putResource(Object key, Object value) {
129 throw new UnsupportedOperationException();
130 }
131
132 @Override
133 public Object getResource(Object key) {
134 throw new UnsupportedOperationException();
135 }
136
137 @Override
138 public void registerInterposedSynchronization(Synchronization sync) {
139 throw new UnsupportedOperationException();
140 }
141
142 @Override
143 public int getTransactionStatus() {
144 try {
145 return getStatus();
146 } catch (SystemException e) {
147 throw new IllegalStateException("Cannot get status", e);
148 }
149 }
150
151 @Override
152 public boolean getRollbackOnly() {
153 try {
154 return getStatus() == Status.STATUS_MARKED_ROLLBACK;
155 } catch (SystemException e) {
156 throw new IllegalStateException("Cannot get status", e);
157 }
158 }
159
160 @Override
161 public void setRollbackOnly() {
162 try {
163 getCurrent().setRollbackOnly();
164 } catch (Exception e) {
165 throw new IllegalStateException("Cannot set rollback only", e);
166 }
167 }
168
169 }
170 }