[pysqlite] Is this error due to my Linux version?
Ed Pasma <[email protected]> Tue, 12 Aug 2008 07:59:18 +0200
| Newsgroups | gmane.comp.python.db.pysqlite.user |
|---|---|
| Message-ID | <[email protected]> |
Hello, can anybody with a Linux system and SQLite 3.5.9 see if attached script reaches the end? (http://home.wanadoo.nl/italy4ever/ thread_io.py.html) It fails on my SuSE 9, 2.4.21 with OperationalError: Library routine called out of sequence (sqlite_misuse). The script measures the effect of sqlite shared-cache mode on performance. The error occurs when this is enabled. It runs fine on OS X and WINNT, but I wish to make a platform independent package. SQLite was built threadsafe for sure. Thanks for any information, Edzard _______________________________________________ list-pysqlite mailing list list-pysqlite-FR6EJeJVuqdwc357pe9rcyQmJico6nz3epZhswDD4dQ@public.gmane.org http://itsystementwicklung.de/cgi-bin/mailman/listinfo/list-pysqlite
thread_io.py
(text/x-python-script, 3.1 KB)
#!/usr/bin/env python
"""
A test that concurrently reads and writes a database.
The test is repeated for various numbers of threads
and for both regular and shared-cache access mode.
"""
import sys, time, random, threading
try:
import pysqlite2.dbapi2 as sqlite3
except:
import sqlite3
sharedcache = True
format = '%12s %12s %12s %12s'
errors = False
def main ():
print format % ('threads', 'sharedcache', 'rows', 'seconds')
print format % ('-------', '-----------', '----', '-------')
for nthreads in 1, 2, 3, 4:
for sharedcache in False, True:
sqlite3.enable_shared_cache (sharedcache)
t0 = time.time ()
con = Connection ('test.db', isolation_level = None)
cur = con.cursor ()
try:
cur.execute ('BEGIN')
cur.execute ('CREATE TABLE IF NOT EXISTS t (c)')
cur.execute ('DELETE FROM t');
for i in range (5000):
cur.execute ('INSERT INTO t VALUES (?)',
(str (credits), ), # 150 bytes
)
cur.execute ('COMMIT')
threads = []
for i in range (nthreads):
threads.append (threading.Thread (
group=None,
target= sub,
name = None,
args = (nthreads, i),
kwargs={},
verbose=None,
))
for i in threads:
i.start ()
for i in threads:
i.join ()
n = cur.execute ('SELECT COUNT (*) FROM t').fetchone () [0]
dt = round (time.time () - t0, 1)
print format % (nthreads, sharedcache, n, dt)
finally:
con.close ()
if errors:
break
def sub (nthreads, nr):
con = Connection ('test.db', isolation_level = None)
cur = con.cursor ()
try:
for i in range (24):
cur.execute ('SELECT COUNT (*) FROM t WHERE c = 0').fetchone () [0]
if i % nthreads == nr:
cur.execute ('BEGIN')
cur.execute ('INSERT INTO t VALUES (?)', (nr, ))
cur.execute ('COMMIT')
time.sleep (.01)
except:
global errors
errors = True
con.close ()
raise
con.close ()
class Connection (sqlite3.Connection):
" use custom Cursor "
def cursor (self):
return Cursor (self)
class Cursor (sqlite3.Cursor):
" add busy handler for shared cache mode "
def execute (self, *args, **kwargs):
t0 = time.time ()
while True:
try:
return sqlite3.Cursor.execute (self, *args, **kwargs)
break
except sqlite3.OperationalError, e:
if 'locked' not in str (e) or \
time.time () - t0 > 5.:
raise
time.sleep (.01)
if __name__ == '__main__':
main ()