1 package org.apache.onami.persist;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import javax.inject.Singleton;
23 import javax.transaction.HeuristicMixedException;
24 import javax.transaction.HeuristicRollbackException;
25 import javax.transaction.NotSupportedException;
26 import javax.transaction.RollbackException;
27 import javax.transaction.Status;
28 import javax.transaction.SystemException;
29 import javax.transaction.UserTransaction;
30 import java.util.Arrays;
31 import java.util.HashSet;
32 import java.util.Set;
33
34 import static org.apache.onami.persist.Preconditions.checkNotNull;
35
36
37
38
39
40 @Singleton
41 class UserTransactionFacade
42 {
43
44
45
46
47 private static final Set<Integer> ROLLBACK_ONLY_STATES = new HashSet<Integer>(
48 Arrays.asList( Status.STATUS_MARKED_ROLLBACK, Status.STATUS_ROLLING_BACK, Status.STATUS_ROLLEDBACK ) );
49
50
51
52
53 private final UserTransaction txn;
54
55
56
57
58
59
60 UserTransactionFacade( UserTransaction txn )
61 {
62 this.txn = checkNotNull( txn, "txn is mandatory!" );
63 }
64
65
66
67
68 void begin()
69 {
70 try
71 {
72 txn.begin();
73 }
74 catch ( NotSupportedException e )
75 {
76 throw new RuntimeException( "nested transactions are not supported by the user transaction " + txn, e );
77 }
78 catch ( SystemException e )
79 {
80 throw new RuntimeException( "unexpected error occurred", e );
81 }
82 }
83
84
85
86
87 void commit()
88 {
89 try
90 {
91 txn.commit();
92 }
93 catch ( SecurityException e )
94 {
95 throw new RuntimeException( "not allowed to commit the transaction", e );
96 }
97 catch ( IllegalStateException e )
98 {
99 throw new RuntimeException( "no transaction associated with userTransaction", e );
100 }
101 catch ( RollbackException e )
102 {
103 throw new RuntimeException( "rollback during commit", e );
104 }
105 catch ( HeuristicMixedException e )
106 {
107 throw new RuntimeException( "heuristic partial rollback during commit", e );
108 }
109 catch ( HeuristicRollbackException e )
110 {
111 throw new RuntimeException( "heuristic rollback during commit", e );
112 }
113 catch ( SystemException e )
114 {
115 throw new RuntimeException( "unexpected error occurred", e );
116 }
117 }
118
119
120
121
122 void rollback()
123 {
124 try
125 {
126 txn.rollback();
127 }
128 catch ( IllegalStateException e )
129 {
130 throw new RuntimeException( "no transaction associated with userTransaction", e );
131 }
132 catch ( SecurityException e )
133 {
134 throw new RuntimeException( "not allowed to rollback the transaction", e );
135 }
136 catch ( SystemException e )
137 {
138 throw new RuntimeException( "unexpected error occurred", e );
139 }
140 }
141
142
143
144
145 void setRollbackOnly()
146 {
147 try
148 {
149 txn.setRollbackOnly();
150 }
151 catch ( IllegalStateException e )
152 {
153 throw new RuntimeException( "no transaction associated with userTransaction", e );
154 }
155 catch ( SystemException e )
156 {
157 throw new RuntimeException( "unexpected error occurred", e );
158 }
159 }
160
161
162
163
164 boolean getRollbackOnly()
165 {
166 return ROLLBACK_ONLY_STATES.contains( getStatus() );
167 }
168
169
170
171
172 boolean isActive()
173 {
174 return getStatus() != Status.STATUS_NO_TRANSACTION;
175 }
176
177
178
179
180
181
182
183 private int getStatus()
184 {
185 try
186 {
187 int status = txn.getStatus();
188 for ( int i = 0; status == Status.STATUS_UNKNOWN && i < 8; i++ )
189 {
190 try
191 {
192 Thread.sleep( ( 30L * i ) + 30L );
193 }
194 catch ( InterruptedException e )
195 {
196
197 }
198 status = txn.getStatus();
199 }
200 return status;
201 }
202 catch ( SystemException e )
203 {
204 throw new RuntimeException( "unexpected error occurred", e );
205 }
206 }
207
208 }