KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > impl > tree > tm > TransactionManagerObserver


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.core.impl.tree.tm;
10
11 import org.jboss.portal.common.transaction.TransactionManagerProvider;
12 import org.jboss.cache.TransactionManagerLookup;
13 import org.apache.log4j.Logger;
14
15 import javax.transaction.TransactionManager JavaDoc;
16 import javax.transaction.NotSupportedException JavaDoc;
17 import javax.transaction.SystemException JavaDoc;
18 import javax.transaction.RollbackException JavaDoc;
19 import javax.transaction.HeuristicMixedException JavaDoc;
20 import javax.transaction.HeuristicRollbackException JavaDoc;
21 import javax.transaction.Transaction JavaDoc;
22 import javax.transaction.InvalidTransactionException JavaDoc;
23 import javax.transaction.Synchronization JavaDoc;
24 import javax.transaction.Status JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
28
29 /**
30  * Wrap a transaction manager and provide observation of its activites. The main reason to use it is to know whenever
31  * a transaction terminates. It is used because it is not possible to use the <code>javax.transaction.Synchronization</code>
32  * callback to perform an activity that must occur after that the transaction has terminated.
33  *
34  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
35  * @version $Revision: 1.3 $
36  */

37 public class TransactionManagerObserver implements TransactionManager JavaDoc, TransactionManagerProvider, TransactionManagerLookup
38 {
39
40    private final Logger log;
41
42    private final TransactionManager JavaDoc tm;
43
44    private final Map JavaDoc txToObservation;
45    private final ThreadLocal JavaDoc threadToObservation;
46
47    public TransactionManagerObserver(TransactionManager JavaDoc tm)
48    {
49       this.log = Logger.getLogger(TransactionManagerObserver.class);
50       this.tm = tm;
51       this.txToObservation = new ConcurrentHashMap();
52       this.threadToObservation = new ThreadLocal JavaDoc();
53    }
54
55    // ******************************************************************************************************************
56

57    public TransactionObservation getObservation()
58    {
59       return (TransactionObservation)threadToObservation.get();
60    }
61
62    // TransactionManager implementation ********************************************************************************
63

64    public void begin() throws NotSupportedException JavaDoc, SystemException JavaDoc
65    {
66       tm.begin();
67
68       //
69
Transaction JavaDoc tx = tm.getTransaction();
70       TransactionObservation observation = new TransactionObservation(this, tx);
71       txToObservation.put(tx, observation);
72       threadToObservation.set(observation);
73    }
74
75    /**
76     * Commit the transaction then broadcast notification.
77     */

78    public void commit() throws RollbackException JavaDoc, HeuristicMixedException JavaDoc, HeuristicRollbackException JavaDoc, SecurityException JavaDoc, IllegalStateException JavaDoc, SystemException JavaDoc
79    {
80       TransactionObservation observation = (TransactionObservation)getTransaction();
81       SynchonizationResult result = new SynchonizationResult();
82       try
83       {
84          // Cleanup the association
85
Transaction JavaDoc tx = observation.tx;
86          txToObservation.remove(tx);
87
88          // Want to know the final vote
89
tx.registerSynchronization(result);
90
91          // Perform commit
92
tm.commit();
93       }
94       catch (RollbackException JavaDoc e)
95       {
96          log.error("Unexpected rollback exception", e);
97       }
98       finally
99       {
100          // Remove observation
101
threadToObservation.set(null);
102
103          //
104
switch (result.status)
105          {
106          case Status.STATUS_COMMITTED:
107             observation.afterCommit();
108             break;
109          case Status.STATUS_ROLLEDBACK:
110             observation.afterRollback();
111             break;
112          default:
113             log.error("Unexpected status code at commit " + result.status);
114          }
115       }
116    }
117
118    /**
119     * Roll back the transaction then broadcast notification.
120     */

121    public void rollback() throws IllegalStateException JavaDoc, SecurityException JavaDoc, SystemException JavaDoc
122    {
123       TransactionObservation observation = (TransactionObservation)threadToObservation.get();
124       SynchonizationResult result = new SynchonizationResult();
125       try
126       {
127          // Cleanup the association
128
Transaction JavaDoc tx = observation.tx;
129          txToObservation.remove(tx);
130
131          // Want to know the final vote
132
tx.registerSynchronization(result);
133
134          // Perform rollback
135
tm.rollback();
136       }
137       catch (RollbackException JavaDoc e)
138       {
139          log.error("Unexpected rollback exception", e);
140       }
141       finally
142       {
143          // Remove observation
144
threadToObservation.set(null);
145
146          //
147
switch (result.status)
148          {
149          case Status.STATUS_COMMITTED:
150             observation.afterCommit();
151             break;
152          case Status.STATUS_ROLLEDBACK:
153             observation.afterRollback();
154             break;
155          default:
156             log.error("Unexpected status code at rollback " + result.status);
157          }
158       }
159    }
160
161    public void setRollbackOnly() throws IllegalStateException JavaDoc, SystemException JavaDoc
162    {
163       tm.setRollbackOnly();
164    }
165
166    public int getStatus() throws SystemException JavaDoc
167    {
168       return tm.getStatus();
169    }
170
171    public Transaction JavaDoc getTransaction() throws SystemException JavaDoc
172    {
173       Transaction JavaDoc tx = tm.getTransaction();
174       if (tx != null)
175       {
176          tx = (TransactionObservation)txToObservation.get(tx);
177       }
178       return tx;
179    }
180
181    public void setTransactionTimeout(int value) throws SystemException JavaDoc
182    {
183       tm.setTransactionTimeout(value);
184    }
185
186    public Transaction JavaDoc suspend() throws SystemException JavaDoc
187    {
188       Transaction JavaDoc tx = tm.suspend();
189       if (tx != null)
190       {
191          threadToObservation.set(null);
192          TransactionObservation observation = (TransactionObservation)txToObservation.get(tx);
193          tx = observation;
194       }
195       return tx;
196    }
197
198    public void resume(Transaction JavaDoc tx) throws InvalidTransactionException JavaDoc, IllegalStateException JavaDoc, SystemException JavaDoc
199    {
200       if (tx != null)
201       {
202          TransactionObservation observation = (TransactionObservation)tx;
203          threadToObservation.set(observation);
204          tx = observation.tx;
205       }
206       tm.resume(tx);
207    }
208
209    // TransactionManagerProvider implementation ************************************************************************
210

211    public TransactionManager JavaDoc getTransactionManager()
212    {
213       return this;
214    }
215
216    private static class SynchonizationResult implements Synchronization JavaDoc
217    {
218       int status = -50; // Some default unlikely value
219
public void beforeCompletion()
220       {
221       }
222       public void afterCompletion(int status)
223       {
224          this.status = status;
225       }
226    }
227 }
228
Popular Tags