]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/osgi/transaction/simple/SimpleTransaction.java
Continue framework clean up.
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / osgi / transaction / simple / SimpleTransaction.java
1 package org.argeo.osgi.transaction.simple;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.transaction.HeuristicMixedException;
7 import javax.transaction.HeuristicRollbackException;
8 import javax.transaction.RollbackException;
9 import javax.transaction.Status;
10 import javax.transaction.Synchronization;
11 import javax.transaction.SystemException;
12 import javax.transaction.Transaction;
13 import javax.transaction.xa.XAException;
14 import javax.transaction.xa.XAResource;
15 import javax.transaction.xa.Xid;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19
20 class SimpleTransaction implements Transaction, Status {
21 private final static Log log = LogFactory.getLog(SimpleTransaction.class);
22
23 private final Xid xid;
24 private int status = Status.STATUS_ACTIVE;
25 private final List<XAResource> xaResources = new ArrayList<XAResource>();
26
27 private final SimpleTransactionManager transactionManager;
28
29 public SimpleTransaction(SimpleTransactionManager transactionManager) {
30 this.xid = new UuidXid();
31 this.transactionManager = transactionManager;
32 }
33
34 @Override
35 public synchronized void commit() throws RollbackException,
36 HeuristicMixedException, HeuristicRollbackException,
37 SecurityException, IllegalStateException, SystemException {
38 status = STATUS_PREPARING;
39 for (XAResource xaRes : xaResources) {
40 if (status == STATUS_MARKED_ROLLBACK)
41 break;
42 try {
43 xaRes.prepare(xid);
44 } catch (XAException e) {
45 status = STATUS_MARKED_ROLLBACK;
46 log.error("Cannot prepare " + xaRes + " for " + xid, e);
47 }
48 }
49 if (status == STATUS_MARKED_ROLLBACK) {
50 rollback();
51 throw new RollbackException();
52 }
53 status = STATUS_PREPARED;
54
55 status = STATUS_COMMITTING;
56 for (XAResource xaRes : xaResources) {
57 if (status == STATUS_MARKED_ROLLBACK)
58 break;
59 try {
60 xaRes.commit(xid, false);
61 } catch (XAException e) {
62 status = STATUS_MARKED_ROLLBACK;
63 log.error("Cannot prepare " + xaRes + " for " + xid, e);
64 }
65 }
66 if (status == STATUS_MARKED_ROLLBACK) {
67 rollback();
68 throw new RollbackException();
69 }
70
71 // complete
72 status = STATUS_COMMITTED;
73 if (log.isDebugEnabled())
74 log.debug("COMMITTED " + xid);
75 clearResources(XAResource.TMSUCCESS);
76 transactionManager.unregister(xid);
77 }
78
79 @Override
80 public synchronized void rollback() throws IllegalStateException,
81 SystemException {
82 status = STATUS_ROLLING_BACK;
83 for (XAResource xaRes : xaResources) {
84 try {
85 xaRes.rollback(xid);
86 } catch (XAException e) {
87 log.error("Cannot rollback " + xaRes + " for " + xid, e);
88 }
89 }
90
91 // complete
92 status = STATUS_ROLLEDBACK;
93 if (log.isDebugEnabled())
94 log.debug("ROLLEDBACK " + xid);
95 clearResources(XAResource.TMFAIL);
96 transactionManager.unregister(xid);
97 }
98
99 @Override
100 public synchronized boolean enlistResource(XAResource xaRes)
101 throws RollbackException, IllegalStateException, SystemException {
102 if (xaResources.add(xaRes)) {
103 try {
104 xaRes.start(getXid(), XAResource.TMNOFLAGS);
105 return true;
106 } catch (XAException e) {
107 log.error("Cannot enlist " + xaRes, e);
108 return false;
109 }
110 } else
111 return false;
112 }
113
114 @Override
115 public synchronized boolean delistResource(XAResource xaRes, int flag)
116 throws IllegalStateException, SystemException {
117 if (xaResources.remove(xaRes)) {
118 try {
119 xaRes.end(getXid(), flag);
120 } catch (XAException e) {
121 log.error("Cannot delist " + xaRes, e);
122 return false;
123 }
124 return true;
125 } else
126 return false;
127 }
128
129 protected void clearResources(int flag) {
130 for (XAResource xaRes : xaResources)
131 try {
132 xaRes.end(getXid(), flag);
133 } catch (XAException e) {
134 log.error("Cannot end " + xaRes, e);
135 }
136 xaResources.clear();
137 }
138
139 @Override
140 public synchronized int getStatus() throws SystemException {
141 return status;
142 }
143
144 @Override
145 public void registerSynchronization(Synchronization sync)
146 throws RollbackException, IllegalStateException, SystemException {
147 throw new UnsupportedOperationException();
148 }
149
150 @Override
151 public void setRollbackOnly() throws IllegalStateException, SystemException {
152 status = STATUS_MARKED_ROLLBACK;
153 }
154
155 @Override
156 public int hashCode() {
157 return xid.hashCode();
158 }
159
160 Xid getXid() {
161 return xid;
162 }
163
164 }