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 [TransactionTableEntry.java]

nameclass, %method, %block, %line, %
TransactionTableEntry.java100% (1/1)100% (30/30)90%  (658/730)92%  (128.2/139)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TransactionTableEntry100% (1/1)100% (30/30)90%  (658/730)92%  (128.2/139)
TransactionTableEntry (): void 100% (1/1)100% (3/3)100% (1/1)
TransactionTableEntry (Xact, TransactionId, int, int): void 100% (1/1)81%  (74/91)88%  (15.9/18)
clone (): Object 100% (1/1)43%  (9/21)50%  (3/6)
getFirstLog (): LogInstant 100% (1/1)90%  (47/52)86%  (7.7/9)
getFirstLogInstantString (): String 100% (1/1)90%  (18/20)95%  (2.9/3)
getGid (): GlobalTransactionId 100% (1/1)96%  (22/23)98%  (5.9/6)
getGlobalTransactionIdString (): String 100% (1/1)94%  (29/31)97%  (4.8/5)
getLastLog (): LogInstant 100% (1/1)96%  (22/23)98%  (5.9/6)
getStatementTextString (): String 100% (1/1)100% (20/20)100% (7/7)
getTransactionIdString (): String 100% (1/1)87%  (27/31)95%  (4.7/5)
getTransactionStatus (): int 100% (1/1)91%  (10/11)95%  (1.9/2)
getTransactionStatusString (): String 100% (1/1)85%  (11/13)92%  (1.8/2)
getTransactionTypeString (): String 100% (1/1)71%  (15/21)67%  (4/6)
getTypeFormatId (): int 100% (1/1)100% (2/2)100% (1/1)
getUsernameString (): String 100% (1/1)100% (15/15)100% (3/3)
getXact (): Xact 100% (1/1)91%  (10/11)95%  (1.9/2)
getXid (): TransactionId 100% (1/1)89%  (17/19)94%  (2.8/3)
getlcc (): void 100% (1/1)100% (26/26)100% (5/5)
isPrepared (): boolean 100% (1/1)94%  (16/17)96%  (1.9/2)
isRecovery (): boolean 100% (1/1)91%  (10/11)95%  (1.9/2)
isUpdate (): boolean 100% (1/1)91%  (10/11)95%  (1.9/2)
needExclusion (): boolean 100% (1/1)91%  (10/11)95%  (1.9/2)
prepareTransaction (): void 100% (1/1)93%  (14/15)98%  (2.9/3)
readExternal (ObjectInput): void 100% (1/1)95%  (55/58)99%  (11.8/12)
removeUpdateTransaction (): void 100% (1/1)93%  (14/15)98%  (3.9/4)
setXact (Xact): void 100% (1/1)100% (4/4)100% (2/2)
toString (): String 100% (1/1)100% (60/60)100% (2/2)
unsetRecoveryStatus (): void 100% (1/1)93%  (14/15)98%  (3.9/4)
updateTransactionStatus (Xact, int, int): void 100% (1/1)89%  (24/27)94%  (3.8/4)
writeExternal (ObjectOutput): void 100% (1/1)94%  (50/53)98%  (9.8/10)

1/*
2 
3   Derby - Class org.apache.derby.impl.store.raw.xact.TransactionTableEntry
4 
5   Copyright 1997, 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.services.sanity.SanityManager;
24import org.apache.derby.iapi.services.io.Formatable;
25import org.apache.derby.iapi.services.io.FormatIdUtil;
26import org.apache.derby.iapi.services.io.StoredFormatIds;
27 
28import org.apache.derby.iapi.error.StandardException;
29import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
30import org.apache.derby.iapi.sql.conn.StatementContext;
31import org.apache.derby.iapi.store.access.TransactionInfo;
32import org.apache.derby.iapi.store.raw.GlobalTransactionId;
33import org.apache.derby.iapi.store.raw.xact.TransactionId;
34import org.apache.derby.iapi.store.raw.log.LogInstant;
35 
36import java.io.ObjectOutput;
37import java.io.ObjectInput;
38import java.io.IOException;
39 
40/**
41        Transaction table entry is used to store all relavent information of a
42        transaction into the transaction table for the use of checkpoint, recovery,
43        Transaction management during Quiesce state, and for dumping transaction table.  Only works
44        with the following classes: TransactionTable, XactFactory, Xact
45        <BR>
46        During run time, whenever any transaction is started, it is put into the
47        transaction table.  Whenever any transaction is closed, it is removed from
48        the transaction table.
49 
50 
51*/
52 
53public class TransactionTableEntry implements Formatable, TransactionInfo, Cloneable
54{
55        // These fields are only populated if this TTE has been read in from the
56        // log.  Otherwise, they are gotten from the transaction object myxact.
57        private TransactionId           xid;
58        private GlobalTransactionId     gid;
59        private LogInstant              firstLog;
60        private LogInstant              lastLog;
61 
62        // this field is always present - it is 0 for read only transaction, this
63    // is a copy of the status from the Xact (the copy is necessary as during
64    // recovery the Xact is shared by all transaction table entries during
65    // redo and undo).
66        private int                     transactionStatus;
67 
68        // fields useful for returning transaction information if read from 
69    // transaction log during recovery
70        private transient Xact    myxact; 
71        private transient boolean update;
72        private transient boolean recovery;         // is this a transaction read 
73                                                // from the log during recovery?
74        private transient boolean needExclusion;    // in a quiesce state , this 
75                                                // transaction needs to be 
76                                                // barred from activation 
77                                                // during quiesce state
78 
79        private boolean isClone;                            // am I a clone made for the 
80                                                // TransactionVTI?
81 
82        private transient LanguageConnectionContext lcc;
83 
84 
85        /* package */
86        // entry attribute
87        static final int UPDATE                = 0x1;
88        static final int RECOVERY        = 0x2;
89        static final int EXCLUDE        = 0x4;
90 
91        TransactionTableEntry(
92    Xact            xact, 
93    TransactionId   tid, 
94    int             status, 
95    int             attribute)
96        {
97                myxact              = xact;
98                xid                 = tid;
99                transactionStatus   = status;
100 
101                update              = (attribute & UPDATE)   != 0;
102                needExclusion       = (attribute & EXCLUDE)  != 0;
103                recovery            = (attribute & RECOVERY) != 0;
104 
105                if (SanityManager.DEBUG)
106                {
107                        SanityManager.ASSERT(tid != null, "tid is null");
108                        if (update && xact.getFirstLogInstant() == null)
109            {
110                                SanityManager.THROWASSERT(
111                    "update transaction has firstLog = null");
112            }
113 
114 
115            /*
116                        if (!update && xact.getFirstLogInstant() != null)
117            {
118                                SanityManager.THROWASSERT(
119                    "read only transaction has firstLog = " + 
120                    xact.getFirstLogInstant());
121            }
122            */
123                }
124 
125                // Normally, we don't need to remember the gid, firstLog and lastLog
126                // because myxact will have the same information.  However, in
127                // recovery, there is only one transaction taking on different identity
128                // as the log is replayed.  Then each transaction table entry has keep
129                // its own identity and not rely on myxact.  These recovery
130                // transactions are materialized in the transaction table via a
131                // readObject in the checkpoint log record, or are added by
132                // addUpdateTransaction when the log is scanned.
133                if (recovery)
134                {
135                        // make a copy of everything
136                        if (SanityManager.DEBUG)
137                        {
138                                SanityManager.ASSERT(update, "recovery but not update");
139 
140                                if (tid != xact.getId())
141                {
142                    SanityManager.THROWASSERT(
143                        "adding a update transaction during recovery " + 
144                        " but the tids doesn't match" +
145                        tid + " " + xact.getId());
146                }
147                        }
148 
149                        gid         = xact.getGlobalId();
150                        firstLog    = xact.getFirstLogInstant();
151                        lastLog     = xact.getLastLogInstant();
152                }
153        }
154 
155        /*
156         * Formatable methods
157         */
158        public TransactionTableEntry()
159        { }
160 
161        public void writeExternal(ObjectOutput out) throws IOException
162        {
163                if (SanityManager.DEBUG)
164                {
165                        SanityManager.ASSERT(!recovery, "writing out a recovery transaction");
166                        SanityManager.ASSERT(update, "writing out read only transaction");
167                        SanityManager.ASSERT(myxact.getFirstLogInstant() != null, 
168                                                                 "myxact.getFirstLogInstant is null");
169                        SanityManager.ASSERT(!isClone, "cannot write out a clone");
170                }
171 
172                // Why is is safe to access first and last log instant in myxact while
173                // this is happening?  Because we only writes out update transaction
174                // during run time.  When a read only transactions becomes an update
175                // transaction , or when an update transaction commits, the beginXact
176                // and endXact log record's doMe method will try to change the
177                // transaction table entry's state to updat and non-update
178                // respectively.  That change needs to go thru the transaction table
179                // which is mutually exclusive to writing out the transaction table.
180                // Since we are only looking at update transactions and it is "stuck"
181                // in update state in the middle of a TransactionTable.writeExternal
182                // call, all the fields we access in myxact is stable (actually the xid
183                // is also stable but we already have it).
184                //
185                out.writeObject(xid);
186                out.writeObject(myxact.getGlobalId());
187                out.writeObject(myxact.getFirstLogInstant());
188                out.writeObject(myxact.getLastLogInstant());
189                out.writeInt(transactionStatus);
190        }
191 
192        public void readExternal(ObjectInput in) 
193                 throws ClassNotFoundException, IOException
194        {
195                // the only time a transaction table entry is written out is to the
196                // log, so this must be read in during recovery.
197                if (SanityManager.DEBUG)
198                        SanityManager.ASSERT(!isClone, "cannot write out a clone");
199 
200                xid = (TransactionId)in.readObject();
201                gid = (GlobalTransactionId)in.readObject();
202                firstLog = (LogInstant)in.readObject();
203                lastLog = (LogInstant)in.readObject();
204                transactionStatus = in.readInt();
205                update = true;
206                recovery = true;
207                needExclusion = true;
208 
209                if (SanityManager.DEBUG)
210                {
211                        SanityManager.ASSERT(xid != null, "read in transaction table entry with null id");
212                        SanityManager.ASSERT(firstLog != null, "read in transaction table entry with firstLog");
213                }
214 
215        }
216 
217 
218        // set my transaction instance variable for a recovery transaction
219        void setXact(Xact xact)
220        {
221        /*
222        RESOLVE (mikem) - prepared transactions now call setXact() when they are
223        not in recovery.
224                if (SanityManager.DEBUG)
225                {
226                        SanityManager.ASSERT(recovery, 
227                                                                 "setting non-recovery transaction table entry xact");
228                        SanityManager.ASSERT(!isClone, "cannot setXact with a clone");
229                }
230        */
231                myxact = xact;
232 
233        }
234 
235        /**
236                Return my format identifier.
237        */
238        public int getTypeFormatId() {
239                return StoredFormatIds.RAW_STORE_TRANSACTION_TABLE_ENTRY;
240        }
241 
242        public String toString()
243        {
244                if (SanityManager.DEBUG)
245                {
246                        StringBuffer str = new StringBuffer(500).
247                                append("Xid=").append(getXid()).
248                                append(" gid=").append(getGid()).
249                                append(" firstLog=").append(getFirstLog()).
250                                append(" lastLog=").append(getLastLog()).
251                                append(" transactionStatus=").append(transactionStatus).
252                                append(" myxact=").append(myxact).
253                                append(" update=").append(update).
254                                append(" recovery=").append(recovery).
255                                append(" prepare=").append(isPrepared()).
256                                append(" needExclusion=").append(needExclusion).
257                                append("\n");
258                        return str.toString();
259                }
260                else
261                        return null;
262        }
263 
264        void updateTransactionStatus(Xact xact, int status, int attribute)
265        {
266                if (SanityManager.DEBUG)
267                {
268                        SanityManager.ASSERT(myxact == xact,
269                                "update transaction status for wrong xact");
270                        SanityManager.ASSERT(!isClone, "cannot change a clone");
271                }
272 
273                this.update = (attribute & UPDATE) != 0;
274        }
275 
276        void removeUpdateTransaction()
277        {
278                if (SanityManager.DEBUG)
279                        SanityManager.ASSERT(!isClone, "cannot change a clone");
280 
281                this.update = false;
282                transactionStatus = 0;
283                
284        }
285 
286        void unsetRecoveryStatus()
287        {
288                if (SanityManager.DEBUG)
289                        SanityManager.ASSERT(!isClone, "cannot change a clone");
290 
291        // RESOLVE (mikem) - this is kind of ugly. move to a better place?
292 
293        firstLog = null;
294 
295                this.recovery = false;
296        }
297 
298        void prepareTransaction()
299        {
300                if (SanityManager.DEBUG)
301                        SanityManager.ASSERT(!isClone, "cannot change a clone");
302 
303                transactionStatus |= Xact.END_PREPARED;
304        }
305 
306    /**************************************************************************
307     * get instance variables
308     **************************************************************************
309     */
310 
311        TransactionId getXid()
312        {
313                if (SanityManager.DEBUG)
314                {
315                        SanityManager.ASSERT(xid != null, "TTE with null xid");
316                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
317                }
318 
319                return xid;
320        }
321 
322        public final GlobalTransactionId getGid()
323        {
324                if (SanityManager.DEBUG)
325                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
326 
327                if (gid != null)
328                        return gid;
329 
330                if (myxact != null)
331                        return myxact.getGlobalId();
332 
333                return null;
334        }
335 
336        LogInstant getFirstLog()
337        {
338                if (SanityManager.DEBUG)
339                {
340                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
341 
342                        if (recovery)
343            {
344                                SanityManager.ASSERT(
345                    firstLog != null, 
346                    "a recovery transaction with a null firstLog");
347            }
348                        else
349            {
350                                SanityManager.ASSERT(
351                    firstLog == null, 
352                    "a normal transaction with a non-null firstLog" +
353                    "myxact.getFirstLogInstant() = " + myxact.getFirstLogInstant());
354            }
355                }
356 
357                if (firstLog != null)
358                        return firstLog;
359 
360                if (myxact != null)
361                        return myxact.getFirstLogInstant();
362 
363                return null;
364        }
365 
366        LogInstant getLastLog()
367        {
368                if (SanityManager.DEBUG)
369                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
370 
371                if (lastLog != null)
372                        return lastLog;
373 
374                if (myxact != null)
375                        return myxact.getLastLogInstant();
376 
377                return null;
378        }
379 
380        public final Xact getXact()
381        {
382                if (SanityManager.DEBUG)
383                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
384 
385                return myxact;
386        }
387 
388        int getTransactionStatus()
389        {
390                if (SanityManager.DEBUG)
391                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
392 
393                return transactionStatus;
394        }
395 
396        boolean isUpdate()
397        {
398                if (SanityManager.DEBUG)
399                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
400 
401                return update;
402        }
403 
404        boolean isRecovery()
405        {
406                if (SanityManager.DEBUG)
407                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
408 
409                return recovery;
410        }
411 
412        boolean isPrepared()
413        {
414                if (SanityManager.DEBUG)
415                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
416 
417                return((transactionStatus & Xact.END_PREPARED) != 0);
418        }
419 
420 
421 
422 
423        public boolean needExclusion()
424        {
425                if (SanityManager.DEBUG)
426                        SanityManager.ASSERT(!isClone, "cannot call method with a clone");
427 
428                return needExclusion;
429        }
430 
431        /**
432                Methods of TransactionInfo
433         */
434        public String getTransactionIdString()
435        {
436                if (SanityManager.DEBUG)
437                {
438                        SanityManager.ASSERT(
439                !recovery, "trying to display recovery transaction");
440                        SanityManager.ASSERT(myxact != null, "my xact is null");
441                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
442                }
443 
444                TransactionId t = myxact.getIdNoCheck();
445                return (t == null) ? "CLOSED" : t.toString();
446        }
447 
448        public String getGlobalTransactionIdString()
449        {
450                if (SanityManager.DEBUG)
451                {
452                        SanityManager.ASSERT(
453                !recovery, "trying to display recovery transaction");
454                        SanityManager.ASSERT(myxact != null, "my xact is null");
455                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
456                }
457 
458                GlobalTransactionId gid = myxact.getGlobalId();
459                return (gid == null) ? null : gid.toString();
460        }
461 
462        public String getUsernameString()
463        {
464                if (SanityManager.DEBUG)
465                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
466 
467                getlcc();
468                return (lcc == null) ? null : lcc.getAuthorizationId();
469        }
470 
471        public String getTransactionTypeString()
472        {
473                if (SanityManager.DEBUG)
474                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
475 
476        if (myxact == null)
477            return null;
478        else if (myxact.getTransName() != null)
479            return myxact.getTransName();
480        else
481            return myxact.getContextId();
482        }
483 
484        public String getTransactionStatusString()
485        {
486                if (SanityManager.DEBUG)
487                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
488 
489                return (myxact == null) ? null : myxact.getState();
490        }
491 
492        public String getStatementTextString()
493        {
494                if (SanityManager.DEBUG)
495                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
496 
497                getlcc();
498                if (lcc != null)
499                {
500                        StatementContext sc = lcc.getStatementContext();
501                        if (sc != null)
502                                return sc.getStatementText() ;
503                }
504                return null;
505 
506        }
507 
508        public String getFirstLogInstantString()
509        {
510                if (SanityManager.DEBUG)
511                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
512 
513                LogInstant logInstant = 
514            (myxact == null) ? null : myxact.getFirstLogInstant();
515 
516                return (logInstant == null) ? null : logInstant.toString();
517 
518        }                
519 
520        private void getlcc()
521        {
522                if (SanityManager.DEBUG)
523                        SanityManager.ASSERT(isClone, "Should only call method on a clone");
524 
525                if (lcc == null && myxact != null && myxact.xc != null)
526                {
527                        XactContext xc = myxact.xc;
528 
529                        lcc = (LanguageConnectionContext)
530                                xc.getContextManager().getContext(
531                    LanguageConnectionContext.CONTEXT_ID);
532                }
533        }
534 
535        /**
536                Cloneable
537         */
538        protected Object clone()
539        {
540                try 
541                {
542                        Object c = super.clone();
543                        ((TransactionTableEntry)c).isClone = true;
544 
545                        return c;
546                }
547                catch (CloneNotSupportedException e) 
548                {
549                        // this should not happen, we are cloneable
550                        if (SanityManager.DEBUG) 
551            {
552                                SanityManager.THROWASSERT(
553                    "TransactionTableEntry cloneable but throws CloneNotSupportedException " + e);
554                        }
555                        return null;
556                }                                
557        }
558}

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