KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > conglomerate > OpenConglomerate


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.conglomerate.OpenConglomerate
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.access.conglomerate;
23
24 import org.apache.derby.iapi.reference.SQLState;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
31 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
32
33 import org.apache.derby.iapi.store.access.ConglomPropertyQueryable;
34 import org.apache.derby.iapi.store.access.ConglomerateController;
35 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
36 import org.apache.derby.iapi.store.access.Qualifier;
37 import org.apache.derby.iapi.store.access.RowUtil;
38 import org.apache.derby.iapi.store.access.SpaceInfo;
39 import org.apache.derby.iapi.store.access.TransactionController;
40
41 import org.apache.derby.iapi.store.raw.ContainerHandle;
42 import org.apache.derby.iapi.store.raw.FetchDescriptor;
43 import org.apache.derby.iapi.store.raw.LockingPolicy;
44 import org.apache.derby.iapi.store.raw.Page;
45 import org.apache.derby.iapi.store.raw.RecordHandle;
46 import org.apache.derby.iapi.store.raw.Transaction;
47
48 import org.apache.derby.iapi.types.DataValueDescriptor;
49
50 import org.apache.derby.iapi.types.RowLocation;
51
52 import java.util.Properties JavaDoc;
53
54
55 /**
56
57 A Generic class which implements the basic functionality needed to operate
58 on an "open" conglomerate. This class assumes the following general things
59 about the access method.
60 <p>
61 The access method is page based and contained in a single container maintained
62 by raw store.
63
64 **/

65
66 public abstract class OpenConglomerate
67 {
68     /**************************************************************************
69      * Fields of the class
70      **************************************************************************
71      */

72
73     /**
74      * The following group of fields are all basic input parameters which are
75      * provided by the calling code when doing any sort of operation requiring
76      * an open conglomerate (openScan(), open(), openCostController(), ...).
77      * These are just saved values from what was initially input.
78      **/

79     private Conglomerate init_conglomerate;
80     private TransactionManager init_xact_manager;
81     private Transaction init_rawtran;
82     private int init_openmode;
83     private int init_lock_level;
84     private DynamicCompiledOpenConglomInfo init_dynamic_info;
85     private boolean init_hold;
86     private LockingPolicy init_locking_policy;
87
88
89     /**
90      * convenience boolean's for various mode's
91      **/

92     private boolean useUpdateLocks;
93     private boolean forUpdate;
94     private boolean getBaseTableLocks;
95
96     /**
97      * scratch space used for stuff like templates, export rows, ...
98      **/

99     private OpenConglomerateScratchSpace runtime_mem;
100
101
102     /*
103      * The open raw store container associated with this open conglomerate
104      **/

105     private ContainerHandle container;
106
107     /**************************************************************************
108      * Constructors for This class:
109      **************************************************************************
110      */

111
112     /**************************************************************************
113      * Private methods for This class:
114      **************************************************************************
115      */

116
117     /**************************************************************************
118      * abstract methods of This class:
119      **************************************************************************
120      */

121
122     /**
123      * Return an "empty" row location object of the correct type.
124      * <p>
125      *
126      * @return The empty Rowlocation.
127      *
128      * @exception StandardException Standard exception policy.
129      **/

130     protected abstract RowLocation newRowLocationTemplate()
131         throws StandardException;
132
133     abstract public int[] getFormatIds();
134
135
136     /**************************************************************************
137      * Public Methods implementing standard store row locking interfaces:
138      * latchPage(RowPosition)
139      * latchPageAndRepositionScan(RowPosition)
140      * lockPositionForRead(RowPosition, aux_pos, moveForwardIfRowDisappears)
141      * lockPositionForWrite(RowPosition, forInsert, wait)
142      * unlockPositionAfterRead(RowPosition)
143      **************************************************************************
144      */

145     /**
146      * Latch the page containing the current RowPosition, and reposition scan.
147      * <p>
148      * Upon return the scan will hold a latch on the page to continue the
149      * scan on. The scan will positioned on the record, just before the
150      * next record to return.
151      *
152      * Note that for both hold cursor and read uncommitted support this routine
153      * handles all cases of either the current position "dissappearing" (either
154      * the row and/or page). The row and/or page can disappear by deleted
155      * space being reclaimed post commit of that delete, and for some reason
156      * the code requesting the reposition does not have locks which prevented
157      * the space reclamation. Both hold cursor and read uncommitted scans are
158      * examples of ways the caller will not prevent space reclamation from
159      * claiming the position.
160      *
161      * This implementation also automatically updates the RowPosition to
162      * point at the slot containing the current RowPosition. This slot
163      * value is only valid while the latch is held.
164      *
165      * @return true if scan had to reposition because a row disappeared.
166      *
167      * @exception StandardException Standard exception policy.
168      **/

169     public boolean latchPageAndRepositionScan(RowPosition pos)
170         throws StandardException
171     {
172         boolean scan_repositioned = false;
173
174         // Get the page the record handle refers to.
175
pos.current_page = null;
176
177         try
178         {
179             if (pos.current_rh != null)
180             {
181                 pos.current_page =
182                     container.getPage(pos.current_rh.getPageNumber());
183             }
184
185         }
186         catch (Throwable JavaDoc t)
187         {
188             // Assume all errors are caused by the page "disappearing", will
189
// handle this by positioning on next page in code below.
190
// Note that in most cases if the page does not exist, getPage()
191
// will return null rather than throw an exception, so this path
192
// is hard to reach.
193

194             // just continue on first record of the next page.
195
// This should only happen if the page on which the scan was
196
// positioned had all of it's row deleted and the page was
197
// purged.
198

199             // This can happen in a cursor held across a commit, where the
200
// scan needs to be repositioned after the first "next()" in the
201
// subsequent reopen() of the held cursor.
202
}
203
204         if (pos.current_page != null)
205         {
206             try
207             {
208                 // reposition scan at the old position, now that latch is held.
209
pos.current_slot =
210                     pos.current_page.getSlotNumber(pos.current_rh);
211             }
212             catch (StandardException se)
213             {
214                 scan_repositioned = true;
215
216                 // The record that the scan was positioned on, no longer exists.
217
// The normal way this happens is if we were positioned on
218
// a deleted row, without holding a lock on it, and while
219
// the scan did not hold the latch on the page a post commit
220
// job purged the row as part of space reclamation. This can
221
// happen in all ISOLATION level scans below serializable.
222
pos.current_slot =
223                     pos.current_page.getNextSlotNumber(pos.current_rh);
224
225                 if (pos.current_slot == -1)
226                 {
227                     // in this case we there are no more rows on this page
228
// to visit, so position on the next page. In this case
229
// the row that the scan was positioned on was purged,
230
// and there exists no rows now which are greater than this
231
// record id.
232

233                     pos.current_page.unlatch();
234                     pos.current_page = null;
235                 }
236                 else
237                 {
238                     // The way scans work, need to position on the row just
239
// before the one to return "next". The first thing the
240
// next loop will do is move the scan forward one row.
241
pos.current_slot--;
242                 }
243             }
244         }
245
246         if (pos.current_page == null)
247         {
248             // position on the next page.
249
long current_pageno;
250
251             if (pos.current_rh != null)
252             {
253                 current_pageno = pos.current_rh.getPageNumber();
254             }
255             else if (pos.current_pageno != ContainerHandle.INVALID_PAGE_NUMBER)
256             {
257                 current_pageno = pos.current_pageno;
258             }
259             else
260             {
261                 // no valid position, return a null page
262
return(false);
263             }
264
265             pos.current_page = container.getNextPage(current_pageno);
266
267             pos.current_slot = Page.FIRST_SLOT_NUMBER - 1;
268
269             // now position is tracked by active page
270
pos.current_pageno = ContainerHandle.INVALID_PAGE_NUMBER;
271
272             scan_repositioned = true;
273         }
274
275         if (scan_repositioned)
276         {
277             pos.current_rh = null;
278         }
279
280         return(scan_repositioned);
281     }
282
283     /**
284      * Latch the page containing the current RowPosition.
285      * <p>
286      * This implementation also automatically updates the RowPosition to
287      * point at the slot containing the current RowPosition. This slot
288      * value is only valid while the latch is held.
289      *
290      * @exception StandardException Standard exception policy.
291      **/

292     public boolean latchPage(RowPosition pos)
293         throws StandardException
294     {
295         pos.current_page = null;
296
297         try
298         {
299             pos.current_page =
300                 container.getPage(pos.current_rh.getPageNumber());
301
302         }
303         catch (Throwable JavaDoc t)
304         {
305             // Assume all errors are caused by the page "disappearing", will
306
// handle this by returning false indicating that row can't be
307
// found. This can easily happen when using read uncommitted
308
// isolation level.
309
}
310
311         if (pos.current_page != null)
312         {
313             try
314             {
315                 pos.current_slot =
316                     pos.current_page.getSlotNumber(pos.current_rh);
317                 
318                 return(true);
319             }
320             catch (Throwable JavaDoc t)
321             {
322                 // Assume all errors are caused by the row "disappearing",
323
// will handle this by returning false indicating that row
324
// can't be found. This can easily happen when using read
325
// uncommitted isolation level.
326

327                 pos.current_page.unlatch();
328                 pos.current_page = null;
329             }
330         }
331
332         return(false);
333     }
334
335
336     /**
337      * Lock row at given row position for read.
338      * <p>
339      * This routine requests a row lock NOWAIT on the row located at the given
340      * RowPosition. If the lock is granted NOWAIT the
341      * routine will return true. If the lock cannot be granted NOWAIT, then
342      * the routine will release the latch on "page" and then it will request
343      * a WAIT lock on the row.
344      * <p>
345      * This implementation:
346      * Assumes latch held on current_page.
347      * If the current_rh field of RowPosition is non-null it is assumed that
348      * we want to lock that record handle and that we don't have a slot number.
349      * If the current_rh field of RowPosition is null, it is assumed the we
350      * want to lock the indicated current_slot. Upon return current_rh will
351      * point to the record handle associated with current_slot.
352      * <p>
353      * After waiting and getting the lock on the row, this routine will fix up
354      * RowPosition to point at the row locked. This means it will get the
355      * page latch again, and it will fix the current_slot to point at the
356      * waited for record handle - it may have moved while waiting on the lock.
357      *
358      * @param pos Position to lock.
359      * @param aux_pos If you have to give up latch to get lock, then also
360      * unlock this position if it is non-null.
361      * @param moveForwardIfRowDisappears
362      * If true, then this routine must handle the case where
363      * the row id we are waiting on disappears when the latch
364      * is released. If false an exception will be thrown if
365      * the row disappears.
366      * @param waitForLock
367      * if true wait for lock, if lock can't be granted NOWAIT,
368      * else if false, throw a lock timeout exception if the
369      * lock can't be granted without waiting.
370      *
371      * @return true if lock granted without releasing the latch, else return
372      * false.
373      *
374      * @exception StandardException Standard exception policy.
375      **/

376     public boolean lockPositionForRead(
377     RowPosition pos,
378     RowPosition aux_pos,
379     boolean moveForwardIfRowDisappears,
380     boolean waitForLock)
381         throws StandardException
382     {
383         if (pos.current_rh == null)
384         {
385             if (SanityManager.DEBUG)
386             {
387                 SanityManager.ASSERT(
388                     pos.current_page != null &&
389                     pos.current_slot != Page.INVALID_SLOT_NUMBER);
390
391             }
392
393             // work around for lockmanager problem with lock/latch releasing.
394
// Get RecordHandle to lock.
395
pos.current_rh =
396                 pos.current_page.getRecordHandleAtSlot(pos.current_slot);
397
398             if (SanityManager.DEBUG)
399             {
400                 // make sure current_rh and current_slot are in sync
401
if (pos.current_slot !=
402                         pos.current_page.getSlotNumber(pos.current_rh))
403                 {
404                     SanityManager.THROWASSERT(
405                         "current_slot = " + pos.current_slot +
406                         "current_rh = " + pos.current_rh +
407                         "current_rh.slot = " +
408                         pos.current_page.getSlotNumber(pos.current_rh));
409                 }
410             }
411         }
412
413         if (SanityManager.DEBUG)
414             SanityManager.ASSERT(pos.current_rh != null);
415
416         boolean lock_granted_with_latch_held =
417             this.container.getLockingPolicy().lockRecordForRead(
418                 init_rawtran, container, pos.current_rh,
419                 false /* NOWAIT */, forUpdate);
420
421         if (!lock_granted_with_latch_held)
422         {
423
424             // Could not get the lock NOWAIT, release latch and wait for lock.
425
pos.current_page.unlatch();
426             pos.current_page = null;
427
428
429             if (aux_pos != null)
430             {
431                 aux_pos.current_page.unlatch();
432                 aux_pos.current_page = null;
433             }
434
435             if (!waitForLock)
436             {
437                 // throw lock timeout error.
438
throw StandardException.newException(SQLState.LOCK_TIMEOUT);
439             }
440
441             this.container.getLockingPolicy().lockRecordForRead(
442                 init_rawtran, container, pos.current_rh,
443                 true /* WAIT */, forUpdate);
444
445             if (moveForwardIfRowDisappears)
446             {
447
448                 if (latchPageAndRepositionScan(pos))
449                 {
450                     if (pos.current_slot != -1)
451                     {
452                         // If scan was repositioned to just before a valid row
453
// on the current page, then move forward and lock and
454
// return that row (slot != -1).
455
//
456
// Let the caller handle the "-1"
457
// case, which may be one of 3 cases - need to go to
458
// slot 1 on current page, need to go to next page,
459
// need to end scan as there is no "next" page. All
460
// 3 cases are handled by the generic scan loop in
461
// GenericScanController.fetchRows().
462

463                         pos.positionAtNextSlot();
464                         lockPositionForRead(pos, aux_pos, true, true);
465
466                     }
467                 }
468             }
469             else
470             {
471                 latchPage(pos);
472             }
473         }
474
475         return(lock_granted_with_latch_held);
476     }
477
478     public boolean lockPositionForWrite(
479     RowPosition pos,
480     boolean forInsert,
481     boolean waitForLock)
482         throws StandardException
483     {
484         if (pos.current_rh == null)
485         {
486             if (SanityManager.DEBUG)
487             {
488                 SanityManager.ASSERT(pos.current_page != null);
489                 SanityManager.ASSERT(
490                     pos.current_slot != Page.INVALID_SLOT_NUMBER);
491
492             }
493
494             // work around for lockmanager problem with lock/latch releasing.
495
// Get RecordHandle to lock.
496
pos.current_rh =
497                 pos.current_page.fetchFromSlot(
498                     null,
499                     pos.current_slot,
500                     RowUtil.EMPTY_ROW,
501                     RowUtil.EMPTY_ROW_FETCH_DESCRIPTOR,
502                     true);
503
504             if (SanityManager.DEBUG)
505             {
506                 // make sure current_rh and current_slot are in sync
507
if (pos.current_slot !=
508                         pos.current_page.getSlotNumber(pos.current_rh))
509                 {
510                     SanityManager.THROWASSERT(
511                         "current_slot = " + pos.current_slot +
512                         "current_rh = " + pos.current_rh +
513                         "current_rh.slot = " +
514                         pos.current_page.getSlotNumber(pos.current_rh));
515                 }
516             }
517         }
518
519         if (SanityManager.DEBUG)
520             SanityManager.ASSERT(pos.current_rh != null);
521
522         boolean lock_granted_with_latch_held =
523             this.container.getLockingPolicy().
524                 lockRecordForWrite(
525                     init_rawtran, pos.current_rh,
526                     forInsert, false /* NOWAIT */);
527
528         if (!lock_granted_with_latch_held)
529         {
530             if (!waitForLock)
531             {
532                 // throw lock timeout error.
533
throw StandardException.newException(SQLState.LOCK_TIMEOUT);
534             }
535
536             // Could not get the lock NOWAIT, release latch and wait for lock.
537
pos.current_page.unlatch();
538             pos.current_page = null;
539
540             if (!waitForLock)
541             {
542                 // throw lock timeout error.
543
throw StandardException.newException(SQLState.LOCK_TIMEOUT);
544             }
545
546             this.container.getLockingPolicy().
547                 lockRecordForWrite(
548                     init_rawtran, pos.current_rh, forInsert, true /* WAIT */);
549
550             latchPage(pos);
551         }
552
553         return(lock_granted_with_latch_held);
554     }
555
556
557     /**
558      * Unlock the record after a previous request to lock it.
559      * <p>
560      * Unlock the record after a previous call to lockRecordForRead(). It is
561      * expected that RowPosition contains information used to lock the record,
562      * Thus it is important if using a single RowPosition to track a scan to
563      * call unlock before you move the position forward to the next record.
564      * <p>
565      * Note that this routine assumes that the row was locked forUpdate if
566      * the OpenConglomerate is forUpdate, else it assumes the record was
567      * locked for read.
568      *
569      * @exception StandardException Standard exception policy.
570      **/

571     public void unlockPositionAfterRead(
572     RowPosition pos)
573         throws StandardException
574     {
575         if (!isClosed())
576             container.getLockingPolicy().
577                 unlockRecordAfterRead(
578                     init_rawtran, container, pos.current_rh, forUpdate,
579                     pos.current_rh_qualified);
580     }
581
582
583     /**************************************************************************
584      * Public Methods implementing ConglomPropertyQueryable Interface:
585      **************************************************************************
586      */

587
588     /**
589      * Request set of properties associated with a table.
590      * <p>
591      * Returns a property object containing all properties that the store
592      * knows about, which are stored persistently by the store. This set
593      * of properties may vary from implementation to implementation of the
594      * store.
595      * <p>
596      * This call is meant to be used only for internal query of the properties
597      * by jbms, for instance by language during bulk insert so that it can
598      * create a new conglomerate which exactly matches the properties that
599      * the original container was created with. This call should not be used
600      * by the user interface to present properties to users as it may contain
601      * properties that are meant to be internal to jbms. Some properties are
602      * meant only to be specified by jbms code and not by users on the command
603      * line.
604      * <p>
605      * Note that not all properties passed into createConglomerate() are stored
606      * persistently, and that set may vary by store implementation.
607      *
608      * @param prop Property list to add properties to. If null, routine will
609      * create a new Properties object, fill it in and return it.
610      *
611      * @exception StandardException Standard exception policy.
612      **/

613     public Properties JavaDoc getInternalTablePropertySet(Properties JavaDoc prop)
614         throws StandardException
615     {
616         Properties JavaDoc ret_properties =
617             ConglomerateUtil.createRawStorePropertySet(prop);
618
619         getTableProperties(ret_properties);
620
621         return(ret_properties);
622     }
623
624     /**
625      * Request the system properties associated with a table.
626      * <p>
627      * Request the value of properties that are associated with a table. The
628      * following properties can be requested:
629      * derby.storage.pageSize
630      * derby.storage.pageReservedSpace
631      * derby.storage.minimumRecordSize
632      * derby.storage.initialPages
633      * <p>
634      * To get the value of a particular property add it to the property list,
635      * and on return the value of the property will be set to it's current
636      * value. For example:
637      *
638      * get_prop(ConglomerateController cc)
639      * {
640      * Properties prop = new Properties();
641      * prop.put("derby.storage.pageSize", "");
642      * cc.getTableProperties(prop);
643      *
644      * System.out.println(
645      * "table's page size = " +
646      * prop.getProperty("derby.storage.pageSize");
647      * }
648      *
649      * @param prop Property list to fill in.
650      *
651      * @exception StandardException Standard exception policy.
652      **/

653     public void getTableProperties(Properties JavaDoc prop)
654         throws StandardException
655     {
656         container.getContainerProperties(prop);
657
658         return;
659     }
660
661     /**************************************************************************
662      * Public Accessors of This class:
663      **************************************************************************
664      */

665     public final TransactionManager getXactMgr()
666     {
667         return(init_xact_manager);
668     }
669
670     public final Transaction getRawTran()
671     {
672         return(init_rawtran);
673     }
674
675     public final ContainerHandle getContainer()
676     {
677         return(container);
678     }
679
680     public final int getOpenMode()
681     {
682         return(init_openmode);
683     }
684     
685     public final Conglomerate getConglomerate()
686     {
687         return(init_conglomerate);
688     }
689
690     public final boolean getHold()
691     {
692         return(init_hold);
693     }
694
695
696     public final boolean isForUpdate()
697     {
698         return(forUpdate);
699     }
700
701     public final boolean isClosed()
702     {
703         return(container == null);
704     }
705
706     public final boolean isUseUpdateLocks()
707     {
708         return(useUpdateLocks);
709     }
710
711     public final OpenConglomerateScratchSpace getRuntimeMem()
712     {
713         return(runtime_mem);
714     }
715
716     /**************************************************************************
717      * Public Methods implementing some ConglomerateController Interfaces:
718      **************************************************************************
719      */

720
721
722     /**
723      * Check consistency of a conglomerate.
724      * <p>
725      * Checks the consistency of the data within a given conglomerate, does not
726      * check consistency external to the conglomerate (ie. does not check that
727      * base table row pointed at by a secondary index actually exists).
728      * <p>
729      * There is no checking in the default implementation, you must override
730      * to get conglomerate specific consistency checking.
731      *
732      * @exception StandardException Standard exception policy.
733      **/

734     public void checkConsistency()
735         throws StandardException
736     {
737         return;
738     }
739
740
741
742     public void debugConglomerate()
743         throws StandardException
744     {
745         if (SanityManager.DEBUG)
746         {
747             SanityManager.DEBUG_PRINT(
748                 "p_heap", "\nHEAP DUMP:containerId " + container.getId());
749
750             // get a template.
751

752             DataValueDescriptor[] row = runtime_mem.get_row_for_export();
753
754             // Print pages of the heap.
755
Page page = container.getFirstPage();
756
757             while (page != null)
758             {
759                 SanityManager.DEBUG_PRINT(
760                     "p_heap", ConglomerateUtil.debugPage(page, 0, false, row));
761
762                 long pageid = page.getPageNumber();
763                 page.unlatch();
764                 page = container.getNextPage(pageid);
765             }
766         }
767
768         return;
769     }
770
771
772     /**
773     Get information about space used by the conglomerate.
774     **/

775     public SpaceInfo getSpaceInfo()
776         throws StandardException
777     {
778         return container.getSpaceInfo();
779     }
780
781     protected boolean isKeyed()
782     {
783         return false;
784     }
785
786     /**
787      * is the open btree table locked?
788      **/

789     protected boolean isTableLocked()
790     {
791         return(init_lock_level == TransactionController.MODE_TABLE);
792     }
793
794     /**************************************************************************
795      * Public Methods of this class:
796      **************************************************************************
797      */

798
799     /**
800      * Open the container.
801      * <p>
802      * Open the container, obtaining necessary locks. Most work is actually
803      * done by RawStore.openContainer().
804      *
805      * @exception StandardException Standard exception policy.
806      **/

807     public ContainerHandle init(
808     ContainerHandle open_container,
809     Conglomerate conglomerate,
810     int[] format_ids,
811     TransactionManager xact_manager,
812     Transaction rawtran,
813     boolean hold,
814     int openmode,
815     int lock_level,
816     LockingPolicy locking_policy,
817     DynamicCompiledOpenConglomInfo dynamic_info)
818         throws StandardException
819     {
820         // save state of all inputs.
821
init_conglomerate = conglomerate;
822         init_xact_manager = xact_manager;
823         init_rawtran = rawtran;
824         init_openmode = openmode;
825         init_lock_level = lock_level;
826         init_dynamic_info = dynamic_info;
827         init_hold = hold;
828         init_locking_policy = locking_policy;
829
830
831         // either use passed in "compiled" runtime scratch space, or create
832
// new space.
833
this.runtime_mem =
834             (dynamic_info != null ?
835              ((OpenConglomerateScratchSpace) dynamic_info) :
836              new OpenConglomerateScratchSpace(format_ids));
837
838         // Is this an open for update or read? This will
839
// be passed down to the raw store fetch methods, which allows
840
// it to do the appropriate locking.
841
this.forUpdate =
842             ((openmode & ContainerHandle.MODE_FORUPDATE) != 0);
843
844         // keep track of whether this open conglomerate should use update locks.
845
this.useUpdateLocks =
846             ((openmode & ContainerHandle.MODE_USE_UPDATE_LOCKS) != 0);
847
848         // If this flag is set, then the client has already locked the row
849
// by accessing it through the secondary index and has already locked
850
// the row, so the base conglomerate need not re-lock the row.
851
this.getBaseTableLocks =
852             ((openmode & ContainerHandle.MODE_SECONDARY_LOCKED) == 0);
853
854         // if the conglomerate is temporary, open with IS_KEPT set.
855
// RESOLVE(mikem): track 1825
856
// don't want to open temp cantainer with IS_KEPT always.
857
if (conglomerate.isTemporary())
858         {
859             init_openmode |= ContainerHandle.MODE_TEMP_IS_KEPT;
860         }
861
862         if (!getBaseTableLocks)
863             init_locking_policy = null;
864
865         // Open the container.
866
this.container =
867             (open_container != null ?
868                  open_container :
869                  rawtran.openContainer(
870                     conglomerate.getId(), init_locking_policy, init_openmode));
871
872         return(this.container);
873     }
874
875     /**
876      * Open the container.
877      * <p>
878      * Open the container, obtaining necessary locks. Most work is actually
879      * done by RawStore.openContainer(). Will only reopen() if the container
880      * is not already open.
881      *
882      * @exception StandardException Standard exception policy.
883      **/

884     public ContainerHandle reopen()
885         throws StandardException
886     {
887         // reget transaction from context manager, in the case of XA
888
// transaction this may have changed.
889
//
890
/* TODO - XA transactions my change the current transaction on the
891          * context stack. Will want to something like:
892          *
893          * init_rawtran = context_manager.getcurrenttransaction()
894          */

895      
896         if (this.container == null)
897         {
898             this.container =
899                  init_rawtran.openContainer(
900                     init_conglomerate.getId(),
901                     init_locking_policy,
902                     init_openmode);
903         }
904
905         return(this.container);
906     }
907
908     /**
909      * Close the container.
910      * <p>
911      * Handles being closed more than once.
912      *
913      * @exception StandardException Standard exception policy.
914      **/

915     public void close()
916         throws StandardException
917     {
918         if (container != null)
919         {
920             container.close();
921             container = null;
922         }
923     }
924 }
925
Popular Tags