]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java
[maven-release-plugin] prepare release v2.3.4
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / transaction / simple / SimpleTransaction.java
1 package org.argeo.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 /** Simple implementation of an XA {@link Transaction}. */
18 class SimpleTransaction implements Transaction, Status {
19 private final Xid xid;
20 private int status = Status.STATUS_ACTIVE;
21 private final List<XAResource> xaResources = new ArrayList<XAResource>();
22
23 private final SimpleTransactionManager transactionManager;
24
25 public SimpleTransaction(SimpleTransactionManager transactionManager) {
26 this.xid = new UuidXid();
27 this.transactionManager = transactionManager;
28 }
29
30 @Override
31 public synchronized void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
32 SecurityException, IllegalStateException, SystemException {
33 status = STATUS_PREPARING;
34 for (XAResource xaRes : xaResources) {
35 if (status == STATUS_MARKED_ROLLBACK)
36 break;
37 try {
38 xaRes.prepare(xid);
39 } catch (XAException e) {
40 status = STATUS_MARKED_ROLLBACK;
41 error("Cannot prepare " + xaRes + " for " + xid, e);
42 }
43 }
44 if (status == STATUS_MARKED_ROLLBACK) {
45 rollback();
46 throw new RollbackException();
47 }
48 status = STATUS_PREPARED;
49
50 status = STATUS_COMMITTING;
51 for (XAResource xaRes : xaResources) {
52 if (status == STATUS_MARKED_ROLLBACK)
53 break;
54 try {
55 xaRes.commit(xid, false);
56 } catch (XAException e) {
57 status = STATUS_MARKED_ROLLBACK;
58 error("Cannot prepare " + xaRes + " for " + xid, e);
59 }
60 }
61 if (status == STATUS_MARKED_ROLLBACK) {
62 rollback();
63 throw new RollbackException();
64 }
65
66 // complete
67 status = STATUS_COMMITTED;
68 clearResources(XAResource.TMSUCCESS);
69 transactionManager.unregister(xid);
70 }
71
72 @Override
73 public synchronized void rollback() throws IllegalStateException, SystemException {
74 status = STATUS_ROLLING_BACK;
75 for (XAResource xaRes : xaResources) {
76 try {
77 xaRes.rollback(xid);
78 } catch (XAException e) {
79 error("Cannot rollback " + xaRes + " for " + xid, e);
80 }
81 }
82
83 // complete
84 status = STATUS_ROLLEDBACK;
85 clearResources(XAResource.TMFAIL);
86 transactionManager.unregister(xid);
87 }
88
89 @Override
90 public synchronized boolean enlistResource(XAResource xaRes)
91 throws RollbackException, IllegalStateException, SystemException {
92 if (xaResources.add(xaRes)) {
93 try {
94 xaRes.start(getXid(), XAResource.TMNOFLAGS);
95 return true;
96 } catch (XAException e) {
97 error("Cannot enlist " + xaRes, e);
98 return false;
99 }
100 } else
101 return false;
102 }
103
104 @Override
105 public synchronized boolean delistResource(XAResource xaRes, int flag)
106 throws IllegalStateException, SystemException {
107 if (xaResources.remove(xaRes)) {
108 try {
109 xaRes.end(getXid(), flag);
110 } catch (XAException e) {
111 error("Cannot delist " + xaRes, e);
112 return false;
113 }
114 return true;
115 } else
116 return false;
117 }
118
119 protected void clearResources(int flag) {
120 for (XAResource xaRes : xaResources)
121 try {
122 xaRes.end(getXid(), flag);
123 } catch (XAException e) {
124 error("Cannot end " + xaRes, e);
125 }
126 xaResources.clear();
127 }
128
129 protected void error(Object obj, Exception e) {
130 System.err.println(obj);
131 e.printStackTrace();
132 }
133
134 @Override
135 public synchronized int getStatus() throws SystemException {
136 return status;
137 }
138
139 @Override
140 public void registerSynchronization(Synchronization sync)
141 throws RollbackException, IllegalStateException, SystemException {
142 throw new UnsupportedOperationException();
143 }
144
145 @Override
146 public void setRollbackOnly() throws IllegalStateException, SystemException {
147 status = STATUS_MARKED_ROLLBACK;
148 }
149
150 @Override
151 public int hashCode() {
152 return xid.hashCode();
153 }
154
155 Xid getXid() {
156 return xid;
157 }
158
159 }