1
# See the file LICENSE for redistribution information.
3
# Copyright (c) 1996-2001
4
# Sleepycat Software. All rights reserved.
9
# TEST Check that page locks are being released properly.
14
puts "Lock005: Page lock release test"
16
# Clean up after previous runs
19
# Open/create the lock region
20
set e [berkdb_env -create -lock -home $testdir -txn -log]
21
error_check_good env_open [is_valid_env $e] TRUE
23
# Open/create the database
24
set db [berkdb open -create -auto_commit -env $e -len 10 -queue q.db]
25
error_check_good dbopen [is_valid_db $db] TRUE
27
# Check that records are locking by trying to
28
# fetch a record on the wrong transaction.
29
puts "\tLock005.a: Verify that we are locking"
31
# Start the first transaction
32
set txn1 [$e txn -nowait]
33
error_check_good txn_begin [is_valid_txn $txn1 $e] TRUE
34
set ret [catch {$db put -txn $txn1 -append record1} recno1]
35
error_check_good dbput_txn1 $ret 0
37
# Start second txn while the first is still running ...
38
set txn2 [$e txn -nowait]
39
error_check_good txn_begin [is_valid_txn $txn2 $e] TRUE
41
# ... and try to get a record from the first txn (should fail)
42
set ret [catch {$db get -txn $txn2 $recno1} res]
43
error_check_good dbget_wrong_record \
44
[is_substr $res "Lock not granted"] 1
47
error_check_good txn1commit [$txn1 commit] 0
49
error_check_good txn2commit [$txn2 commit] 0
50
# The number of locks stays the same here because the first
51
# lock is released and the second lock was never granted.
54
# Test lock behavior for both abort and commit
55
puts "\tLock005.b: Verify locks after abort or commit"
56
foreach endorder {forward reverse} {
57
end_order_test $db $e commit abort $endorder
58
end_order_test $db $e abort commit $endorder
59
end_order_test $db $e commit commit $endorder
60
end_order_test $db $e abort abort $endorder
64
error_check_good db_close [$db close] 0
65
error_check_good env_close [$e close] 0
68
proc end_order_test { db e txn1end txn2end endorder } {
69
# Start one transaction
70
set txn1 [$e txn -nowait]
71
error_check_good txn_begin [is_valid_txn $txn1 $e] TRUE
72
set ret [catch {$db put -txn $txn1 -append record1} recno1]
73
error_check_good dbput_txn1 $ret 0
75
# Check number of locks
78
# Start a second transaction while first is still running
79
set txn2 [$e txn -nowait]
80
error_check_good txn_begin [is_valid_txn $txn2 $e] TRUE
81
set ret [catch {$db put -txn $txn2 -append record2} recno2]
82
error_check_good dbput_txn2 $ret 0
85
# Now commit or abort one txn and make sure the other is okay
86
if {$endorder == "forward"} {
87
# End transaction 1 first
88
puts "\tLock005.b.1: $txn1end txn1 then $txn2end txn2"
89
error_check_good txn_$txn1end [$txn1 $txn1end] 0
92
# txn1 is now ended, but txn2 is still running
93
set ret1 [catch {$db get -txn $txn2 $recno1} res1]
94
set ret2 [catch {$db get -txn $txn2 $recno2} res2]
95
if { $txn1end == "commit" } {
96
error_check_good txn2_sees_txn1 $ret1 0
97
error_check_good txn2_sees_txn2 $ret2 0
99
# transaction 1 was aborted
100
error_check_good txn2_cantsee_txn1 [llength $res1] 0
103
# End transaction 2 second
104
error_check_good txn_$txn2end [$txn2 $txn2end] 0
107
# txn1 and txn2 should both now be invalid
108
# The get no longer needs to be transactional
109
set ret3 [catch {$db get $recno1} res3]
110
set ret4 [catch {$db get $recno2} res4]
112
if { $txn2end == "commit" } {
113
error_check_good txn2_sees_txn1 $ret3 0
114
error_check_good txn2_sees_txn2 $ret4 0
115
error_check_good txn2_has_record2 \
116
[is_substr $res4 "record2"] 1
118
# transaction 2 was aborted
119
error_check_good txn2_cantsee_txn1 $ret3 0
120
error_check_good txn2_aborted [llength $res4] 0
123
} elseif { $endorder == "reverse" } {
124
# End transaction 2 first
125
puts "\tLock005.b.2: $txn2end txn2 then $txn1end txn1"
126
error_check_good txn_$txn2end [$txn2 $txn2end] 0
129
# txn2 is ended, but txn1 is still running
130
set ret1 [catch {$db get -txn $txn1 $recno1} res1]
131
set ret2 [catch {$db get -txn $txn1 $recno2} res2]
132
if { $txn2end == "commit" } {
133
error_check_good txn1_sees_txn1 $ret1 0
134
error_check_good txn1_sees_txn2 $ret2 0
136
# transaction 2 was aborted
137
error_check_good txn1_cantsee_txn2 [llength $res2] 0
140
# End transaction 1 second
141
error_check_good txn_$txn1end [$txn1 $txn1end] 0
144
# txn1 and txn2 should both now be invalid
145
# The get no longer needs to be transactional
146
set ret3 [catch {$db get $recno1} res3]
147
set ret4 [catch {$db get $recno2} res4]
149
if { $txn1end == "commit" } {
150
error_check_good txn1_sees_txn1 $ret3 0
151
error_check_good txn1_sees_txn2 $ret4 0
152
error_check_good txn1_has_record1 \
153
[is_substr $res3 "record1"] 1
155
# transaction 1 was aborted
156
error_check_good txn1_cantsee_txn2 $ret4 0
157
error_check_good txn1_aborted [llength $res3] 0
162
proc how_many_locks { expected env } {
163
set stat [$env lock_stat]
164
set str "Current number of locks"
166
foreach statpair $stat {
167
if { $checked == 1 } {
170
if { [is_substr [lindex $statpair 0] $str] != 0} {
172
set nlocks [lindex $statpair 1]
173
error_check_good expected_nlocks $nlocks $expected
176
error_check_good checked $checked 1