# # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for transaction snapshots # and pragmas that set bdb environment resources set testdir [file dirname $argv0]/../../lang/sql/sqlite/test source $testdir/../../../../test/sql/bdb_util.tcl set ::txn [db eval { PRAGMA bdbsql_max_txn }] set ::locks [db eval { PRAGMA bdbsql_max_locks }] set ::lockers [db eval { PRAGMA bdbsql_max_lockers }] set ::lkobjects [db eval { PRAGMA bdbsql_max_lock_objects }] # # Test the return values of pragmas read_write_concurrency # and snapshot_isolation. do_test bdb_mvcc-1.0 { execsql { PRAGMA multiversion=off } } {0} do_test bdb_mvcc-1.1 { execsql { PRAGMA snapshot_isolation } } {0} do_test bdb_mvcc-1.2 { execsql { PRAGMA multiversion } } {0} do_test bdb_mvcc-1.3 { execsql { PRAGMA multiversion=on } } {1} do_test bdb_mvcc-1.4 { execsql { PRAGMA snapshot_isolation } } {1} do_test bdb_mvcc-1.5 { execsql { PRAGMA multiversion } } {1} # Remaining tests require threads if {[run_thread_tests]==0} { finish_test ; return } do_test bdb_mvcc-3.0 { execsql { PRAGMA multiversion=on } } {1} do_test bdb_mvcc-3.1 { execsql { BEGIN; CREATE TABLE t1(a); CREATE TABLE t2(a); COMMIT; } } {} # Use threads to check that read and writes are concurrent set mvcc_exclusive_thread { set key "" if {[sqlite -has-codec]} { set key "xyzzy" } set ::DB [sqlthread open test.db $key] set rc [ do_test e1 { execsql { BEGIN EXCLUSIVE } } {SQLITE_OK} do_test e2 { execsql { INSERT INTO t2 VALUES(1) } } {SQLITE_OK} do_test e3 { execsql { SELECT * FROM t1 } } {SQLITE_OK} do_test e4 { execsql { COMMIT } } {SQLITE_OK} ] sqlite3_close $DB set rc } # # If reads and writes are concurrent then the following # operations will not deadlock do_test bdb_mvcc-3.2 { db eval { BEGIN; INSERT INTO t1 values(1); } } {} array unset finished thread_spawn finished(0) "" $bdb_thread_procs $mvcc_exclusive_thread after 10000 do_test bdb_mvcc-3.3 { db eval { SELECT * from t2; } } {} do_test bdb_mvcc-3.4 { execsql { COMMIT; } } {} do_test bdb_mvcc-3.5 { vwait finished(0) set ::finished(0) } {} # # Turn off concurrency so that the following operations # deadlock do_test bdb_mvcc-4.0 { execsql { PRAGMA snapshot_isolation=off } } {0} # Executes operations under an exclusive txn set mvcc_exclusive_thread2 { set key "" if {[sqlite -has-codec]} { set key "xyzzy" } set ::DB [sqlthread open test.db $key] set rc [ do_test e21 { execsql { BEGIN EXCLUSIVE } } {SQLITE_OK} do_test e22 { execsql { INSERT INTO t2 VALUES(1) } } {SQLITE_OK} do_test e23 { execsql { SELECT * FROM t1 } } {SQLITE_OK} do_test e24 { execsql { COMMIT } } {SQLITE_OK} ] sqlite3_close $DB set rc } do_test bdb_mvcc-4.1 { db eval { BEGIN; INSERT INTO t1 values(2); } } {} array unset finished thread_spawn finished(0) "" $bdb_thread_procs $mvcc_exclusive_thread2 after 10000 do_test bdb_mvcc-4.2 { catchsql { SELECT * FROM t2 } } {1 {database is locked}} do_test bdb_mvcc-4.3 { execsql { ROLLBACK } } {} do_test bdb_mvcc-4.4 { vwait finished(0) set ::finished(0) } {} catch {close db} finish_test