EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.store.raw.xact]

COVERAGE SUMMARY FOR SOURCE FILE [XactXAResourceManager.java]

nameclass, %method, %block, %line, %
XactXAResourceManager.java100% (1/1)83%  (5/6)83%  (169/204)86%  (37.2/43)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class XactXAResourceManager100% (1/1)83%  (5/6)83%  (169/204)86%  (37.2/43)
XactXAResourceManager (RawStoreFactory, TransactionTable): void 100% (1/1)100% (9/9)100% (4/4)
commit (ContextManager, Xid, boolean): void 100% (1/1)88%  (30/34)85%  (6/7)
find (Xid): ContextManager 100% (1/1)100% (13/13)100% (1/1)
forget (ContextManager, Xid): void 0%   (0/1)0%   (0/22)0%   (0/3)
recover (int): Xid [] 100% (1/1)94%  (93/99)97%  (21.2/22)
rollback (ContextManager, Xid): void 100% (1/1)89%  (24/27)83%  (5/6)

1/*
2 
3   Derby - Class org.apache.derby.impl.store.raw.xact.XactXAResourceManager
4 
5   Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.store.raw.xact;
22 
23import org.apache.derby.iapi.reference.SQLState;
24 
25import org.apache.derby.iapi.services.context.ContextManager;
26 
27import org.apache.derby.iapi.services.sanity.SanityManager;
28 
29import org.apache.derby.iapi.error.StandardException;
30 
31import org.apache.derby.iapi.store.access.xa.XAResourceManager;
32import org.apache.derby.iapi.store.access.xa.XAXactId;
33import org.apache.derby.iapi.store.access.AccessFactoryGlobals;
34 
35import org.apache.derby.iapi.store.raw.GlobalTransactionId;
36import org.apache.derby.iapi.store.raw.RawStoreFactory;
37import org.apache.derby.iapi.store.raw.Transaction;
38 
39 
40import org.apache.derby.impl.store.raw.xact.GlobalXactId;
41import org.apache.derby.impl.store.raw.xact.TransactionTable;
42import org.apache.derby.impl.store.raw.xact.TransactionTableEntry;
43import org.apache.derby.impl.store.raw.xact.Xact;
44 
45import java.util.Enumeration;
46import java.util.Hashtable;
47 
48import javax.transaction.xa.Xid;
49import javax.transaction.xa.XAResource;
50 
51/**
52 
53The XactXAResourceManager implements the Access XAResource interface, which
54provides offline control over two phase commit transactions.  It is expected
55to be used by TM's (transaction manager's), to recover if systems fail while
56transactions are still in-doubt (prepared).
57<P>
58This interface allows access to commit,prepare,abort global transactions
59as part of a two phase commit protocol.  These interfaces have been chosen
60to be exact implementations required to implement the XAResource interfaces
61as part of the JTA standard extension.
62<P>
63It is expected that the following interfaces are only used during the 
64recovery portion of 2 phase commit, when the transaction manager is
65cleaning up after a runtime crash - it is expected that no current context
66managers exist for the Xid's being operated on.  The "online" two phase commit
67protocol will be implemented by calls directly on a TransactionController.
68<P>
69The XAResource interface is a Java mapping of the industry standard XA resource
70manager interface.  Please refer to: X/Open CAE Specification - Distributed 
71Transaction Processing: The XA Specification, X/Open Document No. XO/CAE/91/300
72or ISBN 1 872630 24 3.
73 
74@see org.apache.derby.iapi.store.access.xa.XAResourceManager
75 
76**/
77 
78public class XactXAResourceManager implements XAResourceManager
79{
80    /**************************************************************************
81     * Fields of the class
82     **************************************************************************
83     */
84    private TransactionTable    transaction_table;
85    private RawStoreFactory     rsf;
86 
87    /**************************************************************************
88     * Constructors for This class:
89     **************************************************************************
90     */
91    public XactXAResourceManager(
92    RawStoreFactory     rsf,
93    TransactionTable    tt)
94    {
95        this.rsf               = rsf;
96        this.transaction_table = tt;
97    }
98 
99    /**************************************************************************
100     * Private/Protected methods of This class:
101     **************************************************************************
102     */
103 
104    /**************************************************************************
105     * Public Methods implementing XAResourceManager interface
106     **************************************************************************
107     */
108 
109    /**
110     * This method is called to commit the global transaction specified by xid.
111     * <p>
112     * RESOLVE - how do we map to the "right" XAExceptions.
113     * <p>
114     *
115     * @param cm       The ContextManager returned from the find() call.
116     * @param xid      A global transaction identifier.
117     * @param onePhase If true, the resource manager should use a one-phase
118     *                 commit protocol to commit the work done on behalf of 
119     *                 xid.
120     *
121         * @exception  StandardException  Standard exception policy.
122     **/
123    public void commit(
124    ContextManager  cm,
125    Xid             xid,
126    boolean         onePhase)
127                throws StandardException
128    {
129        Transaction rawtran = 
130            rsf.findUserTransaction(cm, AccessFactoryGlobals.USER_TRANS_NAME);
131 
132        // This may happen if somehow the transaction was committed between
133        // the find() call and now.
134        if (rawtran == null)
135        {
136            throw StandardException.newException(
137                    SQLState.STORE_XA_PROTOCOL_VIOLATION);
138        }
139 
140        if (SanityManager.DEBUG)
141        {
142            SanityManager.ASSERT(rawtran != null);
143 
144            SanityManager.ASSERT(
145                (new GlobalXactId(
146                    xid.getFormatId(),
147                    xid.getGlobalTransactionId(),
148                    xid.getBranchQualifier())).equals(rawtran.getGlobalId()));
149        }
150 
151        rawtran.xa_commit(onePhase);
152    }
153 
154    /**
155     * Find the given Xid in the transaction table.
156     * <p>
157     * This routine is used to find a in-doubt transaction from the list
158     * of Xid's returned from the recover() routine.  
159     * <p>
160     * In the current implementation it is up to the calling routine
161     * to make the returned ContextManager the "current" ContextManager
162     * before calls to commit,abort, or forget.  The caller is responsible
163     * for error handling, ie. calling cleanupOnError() on the correct
164     * ContextManager.
165     * <p>
166     * If the Xid is not in the system, "null" is returned.
167     * RESOLVE - find out from sku if she wants a exception instead?
168     * <p>
169     *
170     * @param xid      A global transaction identifier.
171     *
172     **/
173    public ContextManager find(
174    Xid     xid)
175    {
176        return(
177            transaction_table.findTransactionContextByGlobalId(
178                new GlobalXactId(
179                    xid.getFormatId(),
180                    xid.getGlobalTransactionId(),
181                    xid.getBranchQualifier())));
182    }
183 
184    /**
185     * This method is called to remove the given transaction 
186     * from the transaction table/log.
187     * <p>
188     * Used to let the store remove all record from log and transaction
189     * table of the given transaction.  This should only be used to 
190     * clean up heuristically completed transactions, otherwise commit or
191     * abort should be used to act on other transactions.
192     * <p>
193     *
194     * @param cm       The ContextManager returned from the find() call.
195     * @param xid      A global transaction identifier.
196     *
197         * @exception  StandardException  Standard exception policy.
198     **/
199    public void forget(
200    ContextManager  cm,
201    Xid             xid)
202                throws StandardException
203    {
204        Transaction rawtran = 
205            rsf.findUserTransaction(cm, AccessFactoryGlobals.USER_TRANS_NAME);
206 
207        if (SanityManager.DEBUG)
208        {
209            SanityManager.ASSERT(
210                new GlobalXactId(
211                    xid.getFormatId(),
212                    xid.getGlobalTransactionId(),
213                    xid.getBranchQualifier()).equals(rawtran.getGlobalId()));
214        }
215 
216        // forget should only be called on heuristically completed xacts, which
217        // should not exist in our system.
218        throw StandardException.newException(
219                SQLState.STORE_XA_PROTOCOL_VIOLATION);
220    }
221 
222 
223    /**
224     * This method is called to obtain a list of prepared transactions.
225     * <p>
226     * This call returns a complete list of global transactions which are 
227     * either prepared or heuristically complete.
228     * <p>
229     * The XAResource interface expects a scan type interface, but our
230     * implementation only returns a complete list of transactions.  So to
231     * simulate the scan the following state is maintained.  If TMSTARTSCAN
232     * is specified the complete list is returned.  If recover is called with
233     * TMNOFLAGS is ever called a 0 length array is returned.  
234     *
235         * @return Return a array with 0 or more Xid's which are currently in
236     *         prepared or heuristically completed state.  If an error occurs
237     *         during the operation, an appropriate error is thrown.
238     *
239     * @param flags    combination of the following flags 
240     *                 XAResource.{TMSTARTRSCAN,TMENDRSCAN,TMNOFLAGS}.  
241     *                 TMNOFLAGS must be used when no other flags are used.
242     *
243         * @exception  StandardException  Standard exception policy.
244     **/
245    public Xid[] recover(int flags)
246        throws StandardException
247    {
248        XAXactId[] ret_xid_list;
249 
250        if ((flags & XAResource.TMSTARTRSCAN) != 0)
251        {
252            Hashtable   trans_hashtable = transaction_table.getTableForXA();
253            XAXactId[]  xid_list        = new XAXactId[trans_hashtable.size()];
254            int         num_prepared    = 0;
255 
256            // Need to hold sync while linear searching the hash table.
257            synchronized (trans_hashtable)
258            {
259                int i = 0;
260 
261                for (Enumeration e = trans_hashtable.elements(); 
262                     e.hasMoreElements(); i++) 
263                {
264                    Xact xact = 
265                        ((TransactionTableEntry) e.nextElement()).getXact();
266 
267                    if (xact.isPrepared())
268                    {
269                        GlobalTransactionId xa_id = xact.getGlobalId();
270 
271                        xid_list[i] = 
272                            new XAXactId(
273                                xa_id.getFormat_Id(), 
274                                xa_id.getGlobalTransactionId(), 
275                                xa_id.getBranchQualifier());
276                        num_prepared++;
277                    }
278                }
279            }
280 
281            // now need to squish the nulls out of the array to return. 
282            ret_xid_list = new XAXactId[num_prepared];
283            int ret_index = 0;
284            for (int i = xid_list.length; i-- > 0; )
285            {
286                if (xid_list[i] != null)
287                    ret_xid_list[ret_index++] = xid_list[i];
288            }
289 
290            if (SanityManager.DEBUG)
291            {
292                SanityManager.ASSERT(ret_index == num_prepared);
293            }
294        }
295        else
296        {
297            ret_xid_list = new XAXactId[0];
298        }
299 
300        return(ret_xid_list);
301    }
302 
303    /**
304     * rollback the transaction identified by Xid.
305     * <p>
306     * The given transaction is roll'ed back and it's history is not
307     * maintained in the transaction table or long term log.
308     * <p>
309     *
310     * @param cm       The ContextManager returned from the find() call.
311     * @param xid      A global transaction identifier.
312     *
313         * @exception  StandardException  Standard exception policy.
314     **/
315    public void rollback(
316    ContextManager  cm,
317    Xid             xid)
318        throws StandardException
319    {
320        Transaction rawtran = 
321            rsf.findUserTransaction(cm, AccessFactoryGlobals.USER_TRANS_NAME);
322 
323        // This may happen if somehow the transaction was committed between
324        // the find() call and now.
325        if (rawtran == null)
326        {
327            throw StandardException.newException(
328                    SQLState.STORE_XA_PROTOCOL_VIOLATION);
329        }
330 
331        if (SanityManager.DEBUG)
332        {
333 
334            SanityManager.ASSERT(
335                new GlobalXactId(
336                    xid.getFormatId(),
337                    xid.getGlobalTransactionId(),
338                    xid.getBranchQualifier()).equals(rawtran.getGlobalId()));
339        }
340 
341        rawtran.xa_rollback();
342    }
343 
344    /**************************************************************************
345     * Public Methods of XXXX class:
346     **************************************************************************
347     */
348}

[all classes][org.apache.derby.impl.store.raw.xact]
EMMA 2.0.5312 (C) Vladimir Roubtsov