1
# See the file LICENSE for redistribution information.
3
# Copyright (c) 1996-2002
4
# Sleepycat Software. All rights reserved.
9
# TEST Test deeply nested transactions and many-child transactions.
10
proc recd008 { method {breadth 4} {depth 4} args} {
14
set args [convert_args $method $args]
15
set omethod [convert_method $method]
17
if { [is_record_based $method] == 1 } {
18
puts "Recd008 skipping for method $method"
21
puts "Recd008: $method $breadth X $depth deeply nested transactions"
23
# Create the database and environment.
28
puts "\tRecd008.a: create database"
29
set db [eval {berkdb_open -create} $args $omethod $testdir/$dbfile]
30
error_check_good dbopen [is_valid_db $db] TRUE
32
# Make sure that we have enough entries to span a couple of
36
while { [gets $did str] != -1 && $count < 1000 } {
37
if { [string compare $omethod "-recno"] == 0 } {
38
set key [expr $count + 1]
46
set ret [$db put $key $str]
47
error_check_good put $ret 0
52
error_check_good db_close [$db close] 0
54
set txn_max [expr int([expr pow($breadth,$depth)])]
55
if { $txn_max < 20 } {
58
puts "\tRecd008.b: create environment for $txn_max transactions"
60
set eflags "-mode 0644 -create -txn_max $txn_max \
62
set env_cmd "berkdb_env $eflags"
63
set dbenv [eval $env_cmd]
64
error_check_good env_open [is_valid_env $dbenv] TRUE
69
{ {recd008_parent abort ENV DB $p1 TXNID 1 1 $breadth $depth}
70
"Recd008.c: child abort parent" }
71
{ {recd008_parent commit ENV DB $p1 TXNID 1 1 $breadth $depth}
72
"Recd008.d: child commit parent" }
75
set cmd [subst [lindex $pair 0]]
76
set msg [lindex $pair 1]
77
op_recover abort $testdir $env_cmd $dbfile $cmd $msg
78
recd008_setkval $dbfile $p1
79
op_recover commit $testdir $env_cmd $dbfile $cmd $msg
80
recd008_setkval $dbfile $p1
83
puts "\tRecd008.e: Verify db_printlog can read logfile"
84
set tmpfile $testdir/printlog.out
85
set stat [catch {exec $util_path/db_printlog -h $testdir \
87
error_check_good db_printlog $stat 0
91
proc recd008_setkval { dbfile p1 } {
95
set db [berkdb_open $testdir/$dbfile]
96
error_check_good dbopen [is_valid_db $db] TRUE
98
set kvals($p1) [lindex [lindex $ret 0] 1]
101
# This is a lot like the op_recover procedure. We cannot use that
102
# because it was not meant to be called recursively. This proc
103
# knows about depth/breadth and file naming so that recursive calls
104
# don't overwrite various initial and afterop files, etc.
106
# The basic flow of this is:
108
# Parent begin transaction (in op_recover)
109
# Parent starts children
110
# Recursively call recd008_recover
111
# (children modify p1)
114
# Parent commit/abort (in op_recover)
116
# Recovery test (in op_recover)
117
proc recd008_parent { op env db p1key parent b0 d0 breadth depth } {
122
# Save copy of original data
123
# Acquire lock on data
125
set olddata $kvals($p1key)
126
set ret [$db get -rmw -txn $parent $p1key]
127
set Dret [lindex [lindex $ret 0] 1]
128
error_check_good get_parent_RMW $Dret $olddata
131
# Parent spawns off children
133
set ret [recd008_txn $op $env $db $p1key $parent \
134
$b0 $d0 $breadth $depth]
136
puts "Child runs complete. Parent modifies data."
141
set newdata $olddata.parent
142
set ret [$db put -txn $parent $p1key $newdata]
143
error_check_good db_put $ret 0
146
# Save value in kvals for later comparison
150
set kvals($p1key) $newdata
153
set kvals($p1key) $olddata
159
proc recd008_txn { op env db p1key parent b0 d0 breadth depth } {
160
global log_log_record_types
164
for {set d 1} {$d < $d0} {incr d} {
167
puts "Recd008_txn: $op parent:$parent $breadth $depth ($b0 $d0)"
169
# Save the initial file and open the environment and the file
170
for {set b $b0} {$b <= $breadth} {incr b} {
172
# Begin child transaction
174
set t [$env txn -parent $parent]
175
error_check_bad txn_begin $t NULL
176
error_check_good txn_begin [is_valid_txn $t $env] TRUE
177
set startd [expr $d0 + 1]
178
set child $b:$startd:$t
179
set olddata $kvals($p1key)
180
set newdata $olddata.$child
181
set ret [$db get -rmw -txn $t $p1key]
182
set Dret [lindex [lindex $ret 0] 1]
183
error_check_good get_parent_RMW $Dret $olddata
186
# Recursively call to set up nested transactions/children
188
for {set d $startd} {$d <= $depth} {incr d} {
189
set ret [recd008_txn commit $env $db $p1key $t \
190
$b $d $breadth $depth]
191
set ret [recd008_txn abort $env $db $p1key $t \
192
$b $d $breadth $depth]
197
set ret [$db put -txn $t $p1key $newdata]
198
error_check_good db_put $ret 0
203
for {set d 1} {$d < $startd} {incr d} {
206
puts "Executing txn_$op:$t"
207
error_check_good txn_$op:$t [$t $op] 0
208
for {set d 1} {$d < $startd} {incr d} {
211
set ret [$db get -rmw -txn $parent $p1key]
212
set Dret [lindex [lindex $ret 0] 1]
215
puts "Command executed and committed."
216
error_check_good get_parent_RMW $Dret $newdata
217
set kvals($p1key) $newdata
220
puts "Command executed and aborted."
221
error_check_good get_parent_RMW $Dret $olddata
222
set kvals($p1key) $olddata