1 3 package jodd.jtx; 4 5 import java.util.LinkedList ; 6 import java.util.Map ; 7 import java.util.HashMap ; 8 import java.util.Iterator ; 9 10 15 public class JtxTransactionManager { 16 17 private boolean nestedTransactions; 18 private boolean singleResourceTransaction; 19 private Map resProviders; 20 21 public JtxTransactionManager() { 22 this.nestedTransactions = true; 23 this.singleResourceTransaction = false; 24 this.resProviders = new HashMap (); 25 } 26 27 public boolean isNestedTransactions() { 28 return nestedTransactions; 29 } 30 31 34 public void setNestedTransactions(boolean nestedTransactions) { 35 this.nestedTransactions = nestedTransactions; 36 } 37 38 public boolean isSingleResourceTransaction() { 39 return singleResourceTransaction; 40 } 41 42 48 public void setSingleResourceTransaction(boolean singleResourceTransaction) { 49 this.singleResourceTransaction = singleResourceTransaction; 50 } 51 52 54 55 private static final ThreadLocal TXSTACK = new ThreadLocal () { 56 protected synchronized Object initialValue() { 57 return new LinkedList (); 58 } 59 }; 60 61 66 public JtxTransaction createTransaction(JtxTransactionMode tm) { 67 LinkedList txlist = (LinkedList ) TXSTACK.get(); 68 if (nestedTransactions == false) { 69 if (txlist.isEmpty() == false) { 70 throw new JtxException("Nested transaction are not allowed by current JTX transaction manager."); 71 } 72 } 73 JtxTransaction tx = new JtxTransaction(this, tm); 74 txlist.addLast(tx); 75 return tx; 76 } 77 78 82 public JtxTransaction getTransaction() { 83 LinkedList txlist = (LinkedList ) TXSTACK.get(); 84 if (txlist.isEmpty() == true) { 85 return null; 86 } 87 return (JtxTransaction) txlist.getLast(); 88 } 89 90 96 public boolean isUnderTransaction() { 97 LinkedList txlist = (LinkedList ) TXSTACK.get(); 98 return (txlist.isEmpty() != true); 99 } 100 101 106 public boolean isUnderActiveTransaction() { 107 LinkedList txlist = (LinkedList ) TXSTACK.get(); 108 if (txlist.isEmpty() == true) { 109 return false; 110 } 111 return ((JtxTransaction) txlist.getLast()).isActive(); 112 113 } 114 115 116 117 120 void removeTransaction(JtxTransaction tx) { 121 LinkedList txlist = (LinkedList ) TXSTACK.get(); 122 txlist.remove(tx); 123 } 124 125 126 129 public int totalTransactions() { 130 LinkedList txlist = (LinkedList ) TXSTACK.get(); 131 return txlist.size(); 132 } 133 134 137 public int totalActiveTransactions() { 138 LinkedList txlist = (LinkedList ) TXSTACK.get(); 139 int count = 0; 140 for (int i = 0; i < txlist.size(); i++) { 141 JtxTransaction tx = (JtxTransaction) txlist.get(i); 142 if (tx.isActive() == true) { 143 count++; 144 } 145 } 146 return count; 147 } 148 149 150 153 public void commitAll() { 154 LinkedList txlist = (LinkedList ) TXSTACK.get(); 155 while (txlist.isEmpty() == false) { 156 JtxTransaction tx = (JtxTransaction) txlist.removeLast(); 157 tx.commit(); 158 } 159 } 160 161 164 public void rollbackAll() { 165 LinkedList txlist = (LinkedList ) TXSTACK.get(); 166 while (txlist.isEmpty() == false) { 167 JtxTransaction tx = (JtxTransaction) txlist.removeLast(); 168 tx.rollback(); 169 } 170 } 171 172 173 175 176 177 188 public JtxTransaction requestTransaction(JtxTransactionMode mode) { 189 switch (mode.getPropagation()) { 190 case JtxTransactionMode.PROPAGATION_REQUIRED: return propRequired(mode); 191 case JtxTransactionMode.PROPAGATION_SUPPORTS: return propSupports(); 192 case JtxTransactionMode.PROPAGATION_MANDATORY: return propMandatory(); 193 case JtxTransactionMode.PROPAGATION_REQUIRES_NEW: return propRequiresNew(mode); 194 case JtxTransactionMode.PROPAGATION_NOT_SUPPORTED: return propNotSupported(mode); 195 case JtxTransactionMode.PROPAGATION_NEVER: return propNever(mode); 196 default: 197 throw new JtxException("Invalid transaction propagation value (" + mode.getPropagation() + ')'); 198 } 199 } 200 201 205 private JtxTransaction propRequired(JtxTransactionMode mode) { 206 JtxTransaction currentTx = getTransaction(); 207 if ((currentTx == null) || (currentTx.isAutocommit() == true)) { 208 currentTx = createTransaction(mode); 209 currentTx.begin(); 210 } 211 return currentTx; 212 } 213 214 218 private JtxTransaction propRequiresNew(JtxTransactionMode mode) { 219 JtxTransaction tx = createTransaction(mode); 220 tx.begin(); 221 return tx; 222 } 223 224 228 private JtxTransaction propSupports() { 229 return getTransaction(); 230 } 231 232 236 private JtxTransaction propMandatory() { 237 JtxTransaction currentTx = getTransaction(); 238 if ((currentTx == null) || (currentTx.isAutocommit() == true)) { 239 throw new JtxException("Transaction is mandatory."); 240 } 241 return currentTx; 242 } 243 244 248 private JtxTransaction propNotSupported(JtxTransactionMode mode) { 249 JtxTransaction currentTx = getTransaction(); 250 if (currentTx == null) { 251 return createTransaction(mode); 252 } 253 if (currentTx.isAutocommit() == true) { 254 return currentTx; 255 } 256 return createTransaction(mode); 257 } 258 259 263 private JtxTransaction propNever(JtxTransactionMode mode) { 264 JtxTransaction currentTx = getTransaction(); 265 if ((currentTx != null) && (currentTx.isAutocommit() == false)) { 266 throw new JtxException("Transaction is not allowed."); 267 } 268 if (currentTx == null) { 269 currentTx = createTransaction(mode); 270 } 271 return currentTx; 272 } 273 274 276 279 public void registerResourceManager(JtxResourceManager resourceManager) { 280 resProviders.put(resourceManager.getResourceType(), resourceManager); 281 } 282 283 286 JtxResourceManager lookupResourceManager(String resourceType) { 287 JtxResourceManager resourceManager = (JtxResourceManager) resProviders.get(resourceType); 288 if (resourceManager == null) { 289 throw new JtxException("Unable to find resource manager for resource type: '" + resourceType + "'."); 290 } 291 return resourceManager; 292 } 293 294 302 public JtxResource getResource(String resourceType) { 303 LinkedList txlist = (LinkedList ) TXSTACK.get(); 304 if (txlist.isEmpty() == true) { 305 JtxResourceManager resourceManager = lookupResourceManager(resourceType); 306 return resourceManager.createResource(); 307 } 308 JtxTransaction tx = (JtxTransaction) txlist.getLast(); 309 return tx.getResource(resourceType); 310 } 311 312 313 315 319 public void close() { 320 Iterator it = resProviders.values().iterator(); 321 while (it.hasNext()) { 322 JtxResourceManager resourceManager = (JtxResourceManager) it.next(); 323 resourceManager.close(); 324 } 325 resProviders.clear(); 326 } 327 328 } 329 330 | Popular Tags |