lock.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. # 2001 September 15
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library. The
  12. # focus of this script is database locks.
  13. #
  14. # $Id: lock.test,v 1.40 2009/06/16 17:49:36 drh Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. # Create an alternative connection to the database
  18. #
  19. do_test lock-1.0 {
  20. # Give a complex pathname to stress the path simplification logic in
  21. # the vxworks driver and in test_async.
  22. file mkdir tempdir/t1/t2
  23. sqlite3 db2 ./tempdir/../tempdir/t1/.//t2/../../..//test.db
  24. set dummy {}
  25. } {}
  26. do_test lock-1.1 {
  27. execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
  28. } {}
  29. do_test lock-1.2 {
  30. execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2
  31. } {}
  32. do_test lock-1.3 {
  33. execsql {CREATE TABLE t1(a int, b int)}
  34. execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
  35. } {t1}
  36. do_test lock-1.5 {
  37. catchsql {
  38. SELECT name FROM sqlite_master WHERE type='table' ORDER BY name
  39. } db2
  40. } {0 t1}
  41. do_test lock-1.6 {
  42. execsql {INSERT INTO t1 VALUES(1,2)}
  43. execsql {SELECT * FROM t1}
  44. } {1 2}
  45. # Update: The schema is now brought up to date by test lock-1.5.
  46. # do_test lock-1.7.1 {
  47. # catchsql {SELECT * FROM t1} db2
  48. # } {1 {no such table: t1}}
  49. do_test lock-1.7.2 {
  50. catchsql {SELECT * FROM t1} db2
  51. } {0 {1 2}}
  52. do_test lock-1.8 {
  53. execsql {UPDATE t1 SET a=b, b=a} db2
  54. execsql {SELECT * FROM t1} db2
  55. } {2 1}
  56. do_test lock-1.9 {
  57. execsql {SELECT * FROM t1}
  58. } {2 1}
  59. do_test lock-1.10 {
  60. execsql {BEGIN TRANSACTION}
  61. execsql {UPDATE t1 SET a = 0 WHERE 0}
  62. execsql {SELECT * FROM t1}
  63. } {2 1}
  64. do_test lock-1.11 {
  65. catchsql {SELECT * FROM t1} db2
  66. } {0 {2 1}}
  67. do_test lock-1.12 {
  68. execsql {ROLLBACK}
  69. catchsql {SELECT * FROM t1}
  70. } {0 {2 1}}
  71. do_test lock-1.13 {
  72. execsql {CREATE TABLE t2(x int, y int)}
  73. execsql {INSERT INTO t2 VALUES(8,9)}
  74. execsql {SELECT * FROM t2}
  75. } {8 9}
  76. do_test lock-1.14.1 {
  77. catchsql {SELECT * FROM t2} db2
  78. } {0 {8 9}}
  79. do_test lock-1.14.2 {
  80. catchsql {SELECT * FROM t1} db2
  81. } {0 {2 1}}
  82. do_test lock-1.15 {
  83. catchsql {SELECT * FROM t2} db2
  84. } {0 {8 9}}
  85. do_test lock-1.16 {
  86. db eval {SELECT * FROM t1} qv {
  87. set x [db eval {SELECT * FROM t1}]
  88. }
  89. set x
  90. } {2 1}
  91. do_test lock-1.17 {
  92. db eval {SELECT * FROM t1} qv {
  93. set x [db eval {SELECT * FROM t2}]
  94. }
  95. set x
  96. } {8 9}
  97. # You cannot UPDATE a table from within the callback of a SELECT
  98. # on that same table because the SELECT has the table locked.
  99. #
  100. # 2006-08-16: Reads no longer block writes within the same
  101. # database connection.
  102. #
  103. #do_test lock-1.18 {
  104. # db eval {SELECT * FROM t1} qv {
  105. # set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg]
  106. # lappend r $msg
  107. # }
  108. # set r
  109. #} {1 {database table is locked}}
  110. # But you can UPDATE a different table from the one that is used in
  111. # the SELECT.
  112. #
  113. do_test lock-1.19 {
  114. db eval {SELECT * FROM t1} qv {
  115. set r [catch {db eval {UPDATE t2 SET x=y, y=x}} msg]
  116. lappend r $msg
  117. }
  118. set r
  119. } {0 {}}
  120. do_test lock-1.20 {
  121. execsql {SELECT * FROM t2}
  122. } {9 8}
  123. # It is possible to do a SELECT of the same table within the
  124. # callback of another SELECT on that same table because two
  125. # or more read-only cursors can be open at once.
  126. #
  127. do_test lock-1.21 {
  128. db eval {SELECT * FROM t1} qv {
  129. set r [catch {db eval {SELECT a FROM t1}} msg]
  130. lappend r $msg
  131. }
  132. set r
  133. } {0 2}
  134. # Under UNIX you can do two SELECTs at once with different database
  135. # connections, because UNIX supports reader/writer locks. Under windows,
  136. # this is not possible.
  137. #
  138. if {$::tcl_platform(platform)=="unix"} {
  139. do_test lock-1.22 {
  140. db eval {SELECT * FROM t1} qv {
  141. set r [catch {db2 eval {SELECT a FROM t1}} msg]
  142. lappend r $msg
  143. }
  144. set r
  145. } {0 2}
  146. }
  147. integrity_check lock-1.23
  148. # If one thread has a transaction another thread cannot start
  149. # a transaction. -> Not true in version 3.0. But if one thread
  150. # as a RESERVED lock another thread cannot acquire one.
  151. #
  152. do_test lock-2.1 {
  153. execsql {BEGIN TRANSACTION}
  154. execsql {UPDATE t1 SET a = 0 WHERE 0}
  155. execsql {BEGIN TRANSACTION} db2
  156. set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg]
  157. execsql {ROLLBACK} db2
  158. lappend r $msg
  159. } {1 {database is locked}}
  160. # A thread can read when another has a RESERVED lock.
  161. #
  162. do_test lock-2.2 {
  163. catchsql {SELECT * FROM t2} db2
  164. } {0 {9 8}}
  165. # If the other thread (the one that does not hold the transaction with
  166. # a RESERVED lock) tries to get a RESERVED lock, we do get a busy callback
  167. # as long as we were not orginally holding a READ lock.
  168. #
  169. do_test lock-2.3.1 {
  170. proc callback {count} {
  171. set ::callback_value $count
  172. break
  173. }
  174. set ::callback_value {}
  175. db2 busy callback
  176. # db2 does not hold a lock so we should get a busy callback here
  177. set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
  178. lappend r $msg
  179. lappend r $::callback_value
  180. } {1 {database is locked} 0}
  181. do_test lock-2.3.2 {
  182. set ::callback_value {}
  183. execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2
  184. # This time db2 does hold a read lock. No busy callback this time.
  185. set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
  186. lappend r $msg
  187. lappend r $::callback_value
  188. } {1 {database is locked} {}}
  189. catch {execsql {ROLLBACK} db2}
  190. do_test lock-2.4.1 {
  191. proc callback {count} {
  192. lappend ::callback_value $count
  193. if {$count>4} break
  194. }
  195. set ::callback_value {}
  196. db2 busy callback
  197. # We get a busy callback because db2 is not holding a lock
  198. set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
  199. lappend r $msg
  200. lappend r $::callback_value
  201. } {1 {database is locked} {0 1 2 3 4 5}}
  202. do_test lock-2.4.2 {
  203. proc callback {count} {
  204. lappend ::callback_value $count
  205. if {$count>4} break
  206. }
  207. set ::callback_value {}
  208. db2 busy callback
  209. execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2
  210. # No busy callback this time because we are holding a lock
  211. set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
  212. lappend r $msg
  213. lappend r $::callback_value
  214. } {1 {database is locked} {}}
  215. catch {execsql {ROLLBACK} db2}
  216. do_test lock-2.5 {
  217. proc callback {count} {
  218. lappend ::callback_value $count
  219. if {$count>4} break
  220. }
  221. set ::callback_value {}
  222. db2 busy callback
  223. set r [catch {execsql {SELECT * FROM t1} db2} msg]
  224. lappend r $msg
  225. lappend r $::callback_value
  226. } {0 {2 1} {}}
  227. execsql {ROLLBACK}
  228. # Test the built-in busy timeout handler
  229. #
  230. do_test lock-2.8 {
  231. db2 timeout 400
  232. execsql BEGIN
  233. execsql {UPDATE t1 SET a = 0 WHERE 0}
  234. catchsql {BEGIN EXCLUSIVE;} db2
  235. } {1 {database is locked}}
  236. do_test lock-2.8b {
  237. db2 eval {PRAGMA busy_timeout}
  238. } {400}
  239. do_test lock-2.9 {
  240. db2 timeout 0
  241. execsql COMMIT
  242. } {}
  243. do_test lock-2.9b {
  244. db2 eval {PRAGMA busy_timeout}
  245. } {0}
  246. integrity_check lock-2.10
  247. do_test lock-2.11 {
  248. db2 eval {PRAGMA busy_timeout(400)}
  249. execsql BEGIN
  250. execsql {UPDATE t1 SET a = 0 WHERE 0}
  251. catchsql {BEGIN EXCLUSIVE;} db2
  252. } {1 {database is locked}}
  253. do_test lock-2.11b {
  254. db2 eval {PRAGMA busy_timeout}
  255. } {400}
  256. do_test lock-2.12 {
  257. db2 eval {PRAGMA busy_timeout(0)}
  258. execsql COMMIT
  259. } {}
  260. do_test lock-2.12b {
  261. db2 eval {PRAGMA busy_timeout}
  262. } {0}
  263. integrity_check lock-2.13
  264. # Try to start two transactions in a row
  265. #
  266. do_test lock-3.1 {
  267. execsql {BEGIN TRANSACTION}
  268. set r [catch {execsql {BEGIN TRANSACTION}} msg]
  269. execsql {ROLLBACK}
  270. lappend r $msg
  271. } {1 {cannot start a transaction within a transaction}}
  272. integrity_check lock-3.2
  273. # Make sure the busy handler and error messages work when
  274. # opening a new pointer to the database while another pointer
  275. # has the database locked.
  276. #
  277. do_test lock-4.1 {
  278. db2 close
  279. catch {db eval ROLLBACK}
  280. db eval BEGIN
  281. db eval {UPDATE t1 SET a=0 WHERE 0}
  282. sqlite3 db2 ./test.db
  283. catchsql {UPDATE t1 SET a=0} db2
  284. } {1 {database is locked}}
  285. do_test lock-4.2 {
  286. set ::callback_value {}
  287. set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg]
  288. lappend rc $msg $::callback_value
  289. } {1 {database is locked} {}}
  290. do_test lock-4.3 {
  291. proc callback {count} {
  292. lappend ::callback_value $count
  293. if {$count>4} break
  294. }
  295. db2 busy callback
  296. set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg]
  297. lappend rc $msg $::callback_value
  298. } {1 {database is locked} {0 1 2 3 4 5}}
  299. execsql {ROLLBACK}
  300. # When one thread is writing, other threads cannot read. Except if the
  301. # writing thread is writing to its temporary tables, the other threads
  302. # can still read. -> Not so in 3.0. One thread can read while another
  303. # holds a RESERVED lock.
  304. #
  305. proc tx_exec {sql} {
  306. db2 eval $sql
  307. }
  308. do_test lock-5.1 {
  309. execsql {
  310. SELECT * FROM t1
  311. }
  312. } {2 1}
  313. do_test lock-5.2 {
  314. db function tx_exec tx_exec
  315. catchsql {
  316. INSERT INTO t1(a,b) SELECT 3, tx_exec('SELECT y FROM t2 LIMIT 1');
  317. }
  318. } {0 {}}
  319. ifcapable tempdb {
  320. do_test lock-5.3 {
  321. execsql {
  322. CREATE TEMP TABLE t3(x);
  323. SELECT * FROM t3;
  324. }
  325. } {}
  326. do_test lock-5.4 {
  327. catchsql {
  328. INSERT INTO t3 SELECT tx_exec('SELECT y FROM t2 LIMIT 1');
  329. }
  330. } {0 {}}
  331. do_test lock-5.5 {
  332. execsql {
  333. SELECT * FROM t3;
  334. }
  335. } {8}
  336. do_test lock-5.6 {
  337. catchsql {
  338. UPDATE t1 SET a=tx_exec('SELECT x FROM t2');
  339. }
  340. } {0 {}}
  341. do_test lock-5.7 {
  342. execsql {
  343. SELECT * FROM t1;
  344. }
  345. } {9 1 9 8}
  346. do_test lock-5.8 {
  347. catchsql {
  348. UPDATE t3 SET x=tx_exec('SELECT x FROM t2');
  349. }
  350. } {0 {}}
  351. do_test lock-5.9 {
  352. execsql {
  353. SELECT * FROM t3;
  354. }
  355. } {9}
  356. }
  357. do_test lock-6.1 {
  358. execsql {
  359. CREATE TABLE t4(a PRIMARY KEY, b);
  360. INSERT INTO t4 VALUES(1, 'one');
  361. INSERT INTO t4 VALUES(2, 'two');
  362. INSERT INTO t4 VALUES(3, 'three');
  363. }
  364. set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL]
  365. sqlite3_step $STMT
  366. execsql { DELETE FROM t4 }
  367. execsql { SELECT * FROM sqlite_master } db2
  368. execsql { SELECT * FROM t4 } db2
  369. } {}
  370. do_test lock-6.2 {
  371. execsql {
  372. BEGIN;
  373. INSERT INTO t4 VALUES(1, 'one');
  374. INSERT INTO t4 VALUES(2, 'two');
  375. INSERT INTO t4 VALUES(3, 'three');
  376. COMMIT;
  377. }
  378. execsql { SELECT * FROM t4 } db2
  379. } {1 one 2 two 3 three}
  380. do_test lock-6.3 {
  381. execsql { SELECT a FROM t4 ORDER BY a } db2
  382. } {1 2 3}
  383. do_test lock-6.4 {
  384. execsql { PRAGMA integrity_check } db2
  385. } {ok}
  386. do_test lock-6.5 {
  387. sqlite3_finalize $STMT
  388. } {SQLITE_OK}
  389. # At one point the following set of conditions would cause SQLite to
  390. # retain a RESERVED or EXCLUSIVE lock after the transaction was committed:
  391. #
  392. # * The journal-mode is set to something other than 'delete', and
  393. # * there exists one or more active read-only statements, and
  394. # * a transaction that modified zero database pages is committed.
  395. #
  396. set temp_status unlocked
  397. if {$TEMP_STORE>=2} {set temp_status unknown}
  398. do_test lock-7.1 {
  399. set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL]
  400. sqlite3_step $STMT
  401. } {SQLITE_ROW}
  402. do_test lock-7.2 {
  403. execsql { PRAGMA lock_status }
  404. } [list main shared temp $temp_status]
  405. do_test lock-7.3 {
  406. execsql {
  407. PRAGMA journal_mode = truncate;
  408. BEGIN;
  409. UPDATE t4 SET a = 10 WHERE 0;
  410. COMMIT;
  411. }
  412. execsql { PRAGMA lock_status }
  413. } [list main shared temp $temp_status]
  414. do_test lock-7.4 {
  415. sqlite3_finalize $STMT
  416. } {SQLITE_OK}
  417. do_test lock-999.1 {
  418. rename db2 {}
  419. } {}
  420. finish_test