6

I use sqlite3 command line, from bash.

I spawn multiple processes, all trying to insert into the same sqlite database file.

I often get "database is locked".

According to my reading of documentation (http://www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked) , this should never happen: "SQLITE_LOCKED means the source of contention is internal and comes from the same database connection that received the SQLITE_LOCKED error".

sqlite3 command line is single-threaded, so I would expect SQLITE_BUSY in this situation, but not SQLITE_LOCKED.

Code:

doit() {
   sqlite3 /tmp/db "insert into foo(a,b,c) values(1,2,3);
}

doit &; doit &; doit &

I tried adding PRAGMA busy_timeout=2000; and PRAGMA locking_mode=EXCLUSIVE; for the heck of it, but it didn't help.

sqlite3 -version
3.8.9 2015-04-08 12:16:33 8a8ffc862e96f57aa698f93de10dee28e69f6e09
Dmitry z
  • 3,009
  • 3
  • 13
  • 14

2 Answers2

6

The error message for SQLITE_BUSY is "database is locked"; SQLITE_LOCKED would be "database table is locked".

The following works for me (where no busy_timeout would result in errors):

doit() {
   sqlite3 /tmp/db "pragma busy_timeout=20000; insert into foo(a,b,c) values(1,2,3);"
}
CL.
  • 158,085
  • 15
  • 181
  • 214
5

There's a good answer for this problem on DBA StackExchange. It boils down to running .timeout 1000 at initialization to tell the command line tool to wait 1 second to acquire a lock. I'm not sure if this timeout is the same as the pragma busy_tmeout you reference or if it's different.

Community
  • 1
  • 1
Nelson
  • 22,368
  • 4
  • 32
  • 30