Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / test / tcl / txn014.tcl
1 # See the file LICENSE for redistribution information.
2 #
3 # Copyright (c) 2005, 2012 Oracle and/or its affiliates.  All rights reserved.
4 #
5 # $Id$
6 #
7 # TEST  txn014
8 # TEST  Test of parent and child txns working on the same database.
9 # TEST  A txn that will become a parent create a database.
10 # TEST  A txn that will not become a parent creates another database.
11 # TEST  Start a child txn of the 1st txn.
12 # TEST  Verify that the parent txn is disabled while child is open.
13 # TEST  1. Child reads contents with child handle (should succeed).
14 # TEST  2. Child reads contents with parent handle (should succeed).
15 # TEST  Verify that the non-parent txn can read from its database,
16 # TEST  and that the child txn cannot.
17 # TEST  Return to the child txn.
18 # TEST  3. Child writes with child handle (should succeed).
19 # TEST  4. Child writes with parent handle (should succeed).
20 # TEST
21 # TEST  Commit the child, verify that the parent can write again.
22 # TEST  Check contents of database with a second child.
23 proc txn014 { } {
24         source ./include.tcl
25         global default_pagesize
26
27         set page_size $default_pagesize
28         # If the page size is very small, we increase page size,
29         # so we won't run out of lockers.
30         if { $page_size < 2048 } {
31                 set page_size 2048
32         }
33         set tnum "014"
34         puts "Txn$tnum: Test use of parent and child txns."
35         set parentfile test$tnum.db
36         set nonparentfile test$tnum.db.2
37         set method "-btree"
38
39         # Use 5000 entries so there will be new items on the wordlist
40         # when we double nentries in part h.
41         set nentries 5000
42
43         env_cleanup $testdir
44
45         puts "\tTxn$tnum.a: Create environment."
46         set eflags "-create -mode 0644 -txn -home $testdir"
47         set env [eval {berkdb_env_noerr} $eflags]
48         error_check_good env [is_valid_env $env] TRUE
49
50         # Open a database with parent txn and populate.  We populate
51         # before starting up the child txn, because the only allowed
52         # Berkeley DB calls for a parent txn are beginning child txns,
53         # committing, or aborting.
54
55         puts "\tTxn$tnum.b: Start parent txn and open database."
56         set parent [$env txn]
57         error_check_good parent_begin [is_valid_txn $parent $env] TRUE
58         set db [berkdb_open_noerr -pagesize $page_size \
59             -env $env -txn $parent -create $method $parentfile]
60         populate $db $method $parent $nentries 0 0
61
62         puts "\tTxn$tnum.c: Start non-parent txn and open database."
63         set nonparent [$env txn]
64         error_check_good nonparent_begin [is_valid_txn $nonparent $env] TRUE
65         set db2 [berkdb_open_noerr -pagesize $page_size \
66             -env $env -txn $nonparent -create $method $nonparentfile]
67         populate $db2 $method $nonparent $nentries 0 0
68
69         # Start child txn and open database.  Parent txn is not yet
70         # committed, but the child should be able to read what's there.
71         # The child txn should also be able to use the parent txn.
72
73         puts "\tTxn$tnum.d: Start child txn."
74         set child [$env txn -parent $parent]
75
76         puts "\tTxn$tnum.e: Verify parent is disabled."
77         catch {$db put -txn $parent a a} ret
78         error_check_good \
79             parent_disabled [is_substr $ret "Child transaction is active"] 1
80
81         puts "\tTxn$tnum.f: Get a handle on parent's database using child txn."
82         set childdb [berkdb_open_noerr -pagesize $page_size \
83             -env $env -txn $child $method $parentfile]
84
85         puts "\tTxn$tnum.g: Read database with child txn/child handle,"
86         puts "\tTxn$tnum.g:     and with child txn/parent handle."
87         set did [open $dict]
88         set count 0
89         while { [gets $did str] != -1 && $count < $nentries } {
90                 set key $str
91
92                 # First use child's handle.
93                 set ret [$childdb get -txn $child $key]
94                 error_check_good \
95                     get $ret [list [list $key [pad_data $method $str]]]
96
97                 # Have the child use the parent's handle.
98                 set ret [$db get -txn $child $key]
99                 error_check_good \
100                     get $ret [list [list $key [pad_data $method $str]]]
101                 incr count
102         }
103         close $did
104
105         # Read the last key from the non-parent database, then try
106         # to read the same key using the child txn.  It will fail.
107         puts "\tTxn$tnum.h: Child cannot read data from non-parent."
108         set ret [$db2 get -txn $nonparent $key]
109
110         # Check the return against $key, because $str has gone on to
111         # the next item in the wordlist.
112         error_check_good \
113             np_get $ret [list [list $key [pad_data $method $key]]]
114         catch {$db2 get -txn $child $key} ret
115         error_check_good \
116             child_np_get [is_substr $ret "is still active"] 1
117
118         # The child should also be able to update the database, using
119         # either handle.
120         puts "\tTxn$tnum.i: Write to database with child txn & child handle."
121         populate $childdb $method $child $nentries 0 0
122         puts "\tTxn$tnum.j: Write to database with child txn & parent handle."
123         populate $db $method $child $nentries 0 0
124
125         puts "\tTxn$tnum.k: Commit child, freeing parent."
126         error_check_good child_commit [$child commit] 0
127         error_check_good childdb_close [$childdb close] 0
128
129         puts "\tTxn$tnum.l: Add more entries to db using parent txn."
130         set nentries [expr $nentries * 2]
131         populate $db $method $parent $nentries 0 0
132
133         puts "\tTxn$tnum.m: Start new child txn and read database."
134         set child2 [$env txn -parent $parent]
135         set child2db [berkdb_open_noerr -pagesize $page_size \
136             -env $env -txn $child2 $method $parentfile]
137
138         set did [open $dict]
139         set count 0
140         while { [gets $did str] != -1 && $count < $nentries } {
141                 set key $str
142                 set ret [$child2db get -txn $child2 $key]
143                 error_check_good \
144                     get $ret [list [list $key [pad_data $method $str]]] 1
145                 incr count
146         }
147         close $did
148
149         puts "\tTxn$tnum.n: Clean up."
150         error_check_good child2_commit [$child2 commit] 0
151         error_check_good nonparent_commit [$nonparent commit] 0
152         error_check_good parent_commit [$parent commit] 0
153         error_check_good db_close [$db close] 0
154         error_check_good db2_close [$db2 close] 0
155         error_check_good childdb_close [$child2db close] 0
156         error_check_good env_close [$env close] 0
157 }
158