]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/osgi/transaction/SimpleTransactionManager.java
Mini desktop graalvm packaging.
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / osgi / transaction / SimpleTransactionManager.java
1 package org.argeo.osgi.transaction;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.concurrent.Callable;
7
8 import javax.transaction.xa.XAResource;
9 import javax.transaction.xa.Xid;
10
11 /**
12 * Simple implementation of an XA transaction manager.
13 */
14 public class SimpleTransactionManager
15 // implements TransactionManager, UserTransaction
16 implements WorkControl, WorkTransaction {
17 private ThreadLocal<SimpleTransaction<Integer>> current = new ThreadLocal<SimpleTransaction<Integer>>();
18
19 private Map<Xid, SimpleTransaction<Integer>> knownTransactions = Collections
20 .synchronizedMap(new HashMap<Xid, SimpleTransaction<Integer>>());
21 private TransactionStatusAdapter<Integer> tsa = new JtaStatusAdapter();
22 // private SyncRegistry syncRegistry = new SyncRegistry();
23
24 /*
25 * WORK IMPLEMENTATION
26 */
27 @Override
28 public <T> T required(Callable<T> work) {
29 T res;
30 begin();
31 try {
32 res = work.call();
33 commit();
34 } catch (Exception e) {
35 rollback();
36 throw new SimpleRollbackException(e);
37 }
38 return res;
39 }
40
41 @Override
42 public WorkContext getWorkContext() {
43 return new WorkContext() {
44
45 @Override
46 public void registerXAResource(XAResource resource, String recoveryId) {
47 getTransaction().enlistResource(resource);
48 }
49 };
50 }
51
52 /*
53 * WORK TRANSACTION IMPLEMENTATION
54 */
55
56 @Override
57 public boolean isNoTransactionStatus() {
58 return tsa.getNoTransactionStatus().equals(getStatus());
59 }
60
61 /*
62 * JTA IMPLEMENTATION
63 */
64
65 public void begin()
66 // throws NotSupportedException, SystemException
67 {
68 if (getCurrent() != null)
69 throw new UnsupportedOperationException("Nested transactions are not supported");
70 SimpleTransaction<Integer> transaction = new SimpleTransaction<Integer>(this, tsa);
71 knownTransactions.put(transaction.getXid(), transaction);
72 current.set(transaction);
73 }
74
75 public void commit()
76 // throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
77 // SecurityException, IllegalStateException, SystemException
78 {
79 if (getCurrent() == null)
80 throw new IllegalStateException("No transaction registered with the current thread.");
81 getCurrent().commit();
82 }
83
84 public int getStatus()
85 // throws SystemException
86 {
87 if (getCurrent() == null)
88 return tsa.getNoTransactionStatus();
89 return getTransaction().getStatus();
90 }
91
92 public SimpleTransaction<Integer> getTransaction()
93 // throws SystemException
94 {
95 return getCurrent();
96 }
97
98 protected SimpleTransaction<Integer> getCurrent()
99 // throws SystemException
100 {
101 SimpleTransaction<Integer> transaction = current.get();
102 if (transaction == null)
103 return null;
104 Integer status = transaction.getStatus();
105 if (status.equals(tsa.getCommittedStatus()) || status.equals(tsa.getRolledBackStatus())) {
106 current.remove();
107 return null;
108 }
109 return transaction;
110 }
111
112 void unregister(Xid xid) {
113 knownTransactions.remove(xid);
114 }
115
116 public void resume(SimpleTransaction<Integer> tobj)
117 // throws InvalidTransactionException, IllegalStateException, SystemException
118 {
119 if (getCurrent() != null)
120 throw new IllegalStateException("Transaction " + current.get() + " already registered");
121 current.set(tobj);
122 }
123
124 public void rollback()
125 // throws IllegalStateException, SecurityException, SystemException
126 {
127 if (getCurrent() == null)
128 throw new IllegalStateException("No transaction registered with the current thread.");
129 getCurrent().rollback();
130 }
131
132 public void setRollbackOnly()
133 // throws IllegalStateException, SystemException
134 {
135 if (getCurrent() == null)
136 throw new IllegalStateException("No transaction registered with the current thread.");
137 getCurrent().setRollbackOnly();
138 }
139
140 public void setTransactionTimeout(int seconds)
141 // throws SystemException
142 {
143 throw new UnsupportedOperationException();
144 }
145
146 public SimpleTransaction<Integer> suspend()
147 // throws SystemException
148 {
149 SimpleTransaction<Integer> transaction = getCurrent();
150 current.remove();
151 return transaction;
152 }
153
154 // public TransactionSynchronizationRegistry getTsr() {
155 // return syncRegistry;
156 // }
157 //
158 // private class SyncRegistry implements TransactionSynchronizationRegistry {
159 // @Override
160 // public Object getTransactionKey() {
161 // try {
162 // SimpleTransaction transaction = getCurrent();
163 // if (transaction == null)
164 // return null;
165 // return getCurrent().getXid();
166 // } catch (SystemException e) {
167 // throw new IllegalStateException("Cannot get transaction key", e);
168 // }
169 // }
170 //
171 // @Override
172 // public void putResource(Object key, Object value) {
173 // throw new UnsupportedOperationException();
174 // }
175 //
176 // @Override
177 // public Object getResource(Object key) {
178 // throw new UnsupportedOperationException();
179 // }
180 //
181 // @Override
182 // public void registerInterposedSynchronization(Synchronization sync) {
183 // throw new UnsupportedOperationException();
184 // }
185 //
186 // @Override
187 // public int getTransactionStatus() {
188 // try {
189 // return getStatus();
190 // } catch (SystemException e) {
191 // throw new IllegalStateException("Cannot get status", e);
192 // }
193 // }
194 //
195 // @Override
196 // public boolean getRollbackOnly() {
197 // try {
198 // return getStatus() == Status.STATUS_MARKED_ROLLBACK;
199 // } catch (SystemException e) {
200 // throw new IllegalStateException("Cannot get status", e);
201 // }
202 // }
203 //
204 // @Override
205 // public void setRollbackOnly() {
206 // try {
207 // getCurrent().setRollbackOnly();
208 // } catch (Exception e) {
209 // throw new IllegalStateException("Cannot set rollback only", e);
210 // }
211 // }
212 //
213 // }
214 }