1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.util;
18
19 import java.lang.reflect.InvocationTargetException;
20
21 import net.sf.ehcache.CacheException;
22 import net.sf.ehcache.Ehcache;
23 import net.sf.ehcache.TransactionController;
24
25 /***
26 * A collection of utility methods helping controlling transactions for managed operations which may require them.
27 *
28 * @author Ludovic Orban
29 */
30 public class CacheTransactionHelper {
31
32 private static final int XA_STATUS_NO_TRANSACTION = 6;
33
34 /***
35 * Begin a transaction on the current thread if the cache is configured as transactional,
36 * otherwise this method does nothing.
37 *
38 * @param cache the cache to begin a transaction for
39 * @throws CacheException if anything wrong happens
40 */
41 public static void beginTransactionIfNeeded(Ehcache cache) throws CacheException {
42 try {
43 switch (cache.getCacheConfiguration().getTransactionalMode()) {
44 case LOCAL:
45 TransactionController ctrl = cache.getCacheManager().getTransactionController();
46 ctrl.begin();
47 break;
48
49 case XA:
50 case XA_STRICT:
51 Object tm = ((net.sf.ehcache.Cache) cache).getTransactionManagerLookup().getTransactionManager();
52 tm.getClass().getMethod("begin").invoke(tm);
53 break;
54
55 case OFF:
56 default:
57 break;
58 }
59 } catch (Exception e) {
60 e.printStackTrace();
61 throw new CacheException("error beginning transaction:" + e);
62 }
63 }
64
65 /***
66 * Commit a transaction previously begun on the current thread if the cache is configured as
67 * transactional, otherwise this method does nothing.
68 *
69 * @param cache the cache to commit a transaction for
70 * @throws CacheException if anything wrong happens
71 */
72 public static void commitTransactionIfNeeded(Ehcache cache) throws CacheException {
73 try {
74 switch (cache.getCacheConfiguration().getTransactionalMode()) {
75 case LOCAL:
76 TransactionController ctrl = cache.getCacheManager().getTransactionController();
77 ctrl.commit();
78 break;
79
80 case XA:
81 case XA_STRICT:
82 Object tm = ((net.sf.ehcache.Cache) cache).getTransactionManagerLookup().getTransactionManager();
83 tm.getClass().getMethod("commit").invoke(tm);
84 break;
85
86 case OFF:
87 default:
88 break;
89 }
90 } catch (Exception e) {
91 Throwable t = e;
92 if (t instanceof InvocationTargetException) {
93 t = ((InvocationTargetException)e).getCause();
94 }
95 throw new CacheException("error committing transaction: " + t);
96 }
97 }
98
99 /***
100 * Check if a transaction has begun on the current thread if the cache is configured as
101 * transactional, otherwise always return false.
102 * @param cache the cache to check if a transaction started for
103 * @return true if the cache is transactional and a transaction started, false otherwise
104 * @throws CacheException if anything wrong happens
105 */
106 public static boolean isTransactionStarted(Ehcache cache) throws CacheException {
107 try {
108 switch (cache.getCacheConfiguration().getTransactionalMode()) {
109 case LOCAL:
110 TransactionController ctrl = cache.getCacheManager().getTransactionController();
111 return ctrl.getCurrentTransactionContext() != null;
112
113 case XA:
114 case XA_STRICT:
115 Object tm = ((net.sf.ehcache.Cache) cache).getTransactionManagerLookup().getTransactionManager();
116 return ((Integer) tm.getClass().getMethod("getStatus").invoke(tm)) != XA_STATUS_NO_TRANSACTION;
117
118 case OFF:
119 default:
120 return false;
121 }
122 } catch (Exception e) {
123 e.printStackTrace();
124 throw new CacheException("error checking if transaction started: " + e);
125 }
126 }
127
128 }