View Javadoc

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 }