1 # See the file LICENSE for redistribution information.
3 # Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
8 # TEST Check that page locks are being released properly.
13 puts "Lock005: Page lock release test"
15 # Clean up after previous runs
18 # Open/create the lock region
19 set e [berkdb_env -create -lock -home $testdir -txn -log]
20 error_check_good env_open [is_valid_env $e] TRUE
22 # Open/create the database
23 set db [berkdb open -create -auto_commit -env $e -len 10 -queue q.db]
24 error_check_good dbopen [is_valid_db $db] TRUE
26 # Check that records are locking by trying to
27 # fetch a record on the wrong transaction.
28 puts "\tLock005.a: Verify that we are locking"
30 # Start the first transaction
31 set txn1 [$e txn -nowait]
32 error_check_good txn_begin [is_valid_txn $txn1 $e] TRUE
33 set ret [catch {$db put -txn $txn1 -append record1} recno1]
34 error_check_good dbput_txn1 $ret 0
36 # Start second txn while the first is still running ...
37 set txn2 [$e txn -nowait]
38 error_check_good txn_begin [is_valid_txn $txn2 $e] TRUE
40 # ... and try to get a record from the first txn (should fail)
41 set ret [catch {$db get -txn $txn2 $recno1} res]
42 error_check_good dbget_wrong_record \
43 [is_substr $res "deadlock"] 1
46 error_check_good txn1commit [$txn1 commit] 0
48 error_check_good txn2commit [$txn2 commit] 0
49 # The number of locks stays the same here because the first
50 # lock is released and the second lock was never granted.
53 # Test lock behavior for both abort and commit
54 puts "\tLock005.b: Verify locks after abort or commit"
55 foreach endorder {forward reverse} {
56 end_order_test $db $e commit abort $endorder
57 end_order_test $db $e abort commit $endorder
58 end_order_test $db $e commit commit $endorder
59 end_order_test $db $e abort abort $endorder
63 error_check_good db_close [$db close] 0
64 error_check_good env_close [$e close] 0
67 proc end_order_test { db e txn1end txn2end endorder } {
68 # Start one transaction
69 set txn1 [$e txn -nowait]
70 error_check_good txn_begin [is_valid_txn $txn1 $e] TRUE
71 set ret [catch {$db put -txn $txn1 -append record1} recno1]
72 error_check_good dbput_txn1 $ret 0
74 # Check number of locks
77 # Start a second transaction while first is still running
78 set txn2 [$e txn -nowait]
79 error_check_good txn_begin [is_valid_txn $txn2 $e] TRUE
80 set ret [catch {$db put -txn $txn2 -append record2} recno2]
81 error_check_good dbput_txn2 $ret 0
84 # Now commit or abort one txn and make sure the other is okay
85 if {$endorder == "forward"} {
86 # End transaction 1 first
87 puts "\tLock005.b.1: $txn1end txn1 then $txn2end txn2"
88 error_check_good txn_$txn1end [$txn1 $txn1end] 0
91 # txn1 is now ended, but txn2 is still running
92 set ret1 [catch {$db get -txn $txn2 $recno1} res1]
93 set ret2 [catch {$db get -txn $txn2 $recno2} res2]
94 if { $txn1end == "commit" } {
95 error_check_good txn2_sees_txn1 $ret1 0
96 error_check_good txn2_sees_txn2 $ret2 0
98 # transaction 1 was aborted
99 error_check_good txn2_cantsee_txn1 [llength $res1] 0
102 # End transaction 2 second
103 error_check_good txn_$txn2end [$txn2 $txn2end] 0
106 # txn1 and txn2 should both now be invalid
107 # The get no longer needs to be transactional
108 set ret3 [catch {$db get $recno1} res3]
109 set ret4 [catch {$db get $recno2} res4]
111 if { $txn2end == "commit" } {
112 error_check_good txn2_sees_txn1 $ret3 0
113 error_check_good txn2_sees_txn2 $ret4 0
114 error_check_good txn2_has_record2 \
115 [is_substr $res4 "record2"] 1
117 # transaction 2 was aborted
118 error_check_good txn2_cantsee_txn1 $ret3 0
119 error_check_good txn2_aborted [llength $res4] 0
122 } elseif { $endorder == "reverse" } {
123 # End transaction 2 first
124 puts "\tLock005.b.2: $txn2end txn2 then $txn1end txn1"
125 error_check_good txn_$txn2end [$txn2 $txn2end] 0
128 # txn2 is ended, but txn1 is still running
129 set ret1 [catch {$db get -txn $txn1 $recno1} res1]
130 set ret2 [catch {$db get -txn $txn1 $recno2} res2]
131 if { $txn2end == "commit" } {
132 error_check_good txn1_sees_txn1 $ret1 0
133 error_check_good txn1_sees_txn2 $ret2 0
135 # transaction 2 was aborted
136 error_check_good txn1_cantsee_txn2 [llength $res2] 0
139 # End transaction 1 second
140 error_check_good txn_$txn1end [$txn1 $txn1end] 0
143 # txn1 and txn2 should both now be invalid
144 # The get no longer needs to be transactional
145 set ret3 [catch {$db get $recno1} res3]
146 set ret4 [catch {$db get $recno2} res4]
148 if { $txn1end == "commit" } {
149 error_check_good txn1_sees_txn1 $ret3 0
150 error_check_good txn1_sees_txn2 $ret4 0
151 error_check_good txn1_has_record1 \
152 [is_substr $res3 "record1"] 1
154 # transaction 1 was aborted
155 error_check_good txn1_cantsee_txn2 $ret4 0
156 error_check_good txn1_aborted [llength $res3] 0
161 proc how_many_locks { expected env } {
162 set stat [$env lock_stat]
163 set str "Current number of locks"
165 foreach statpair $stat {
166 if { $checked == 1 } {
169 if { [is_substr [lindex $statpair 0] $str] != 0} {
171 set nlocks [lindex $statpair 1]
172 error_check_good expected_nlocks $nlocks $expected
175 error_check_good checked $checked 1