Help! I'm running into a serious and puzzling problem running multiple
web2py shell processes against a common database.  I'm using web2py
1.97 and sqlite3 under Linux Mint 10 with an ext4 file system.   In a
nutshell, the problem is that I'm getting various DatabaseErrors when
one process attempts to read while another is inserting or updating. I
was under the impression that the DAL would apply the necessary locks
to prevent this kind of conflict but it's not working out very well.
I've made sure all my inserts and updates are wrapped in code (see
below) that performs rollbacks and retries.  Do I also need to
manually lock the db (and if so, how)?

One puzzling aspect of this problem is that while it occurs repeatably
on different machines running Linux,  I do not see it when testing the
same code under OS X.

Any advice appreciated!

-----------  ERROR EXAMPLE------------------
In this example process id 20180 has entered the update routine and process id
19980 attempted a query that failed when SQLite reported a "malformed" error.
The update, however, succeeded with no errors reported.
---------------------------------------------------------
DEBUG:20180:Entering db_update().
ERROR:19980:Traceback (most recent call last):
  File "applications/sunrex/modules/fls_data_handler.py", line 631, in
runMissingReports
    create_missing_report_records(earliest, end)
  File "applications/sunrex/modules/fls_data_handler.py", line 428, in
create_missing_report_records
    rows = db(qry).select(tbl.ALL).as_list()
  File "/home/solarmax/web2py/gluon/dal.py", line 5394, in select
    return self.db._adapter.select(self.query,fields,attributes)
  File "/home/solarmax/web2py/gluon/dal.py", line 1176, in select
    rows = response(sql)
  File "/home/solarmax/web2py/gluon/dal.py", line 1166, in response
    self.execute(sql)
  File "/home/solarmax/web2py/gluon/dal.py", line 1251, in execute
    return self.log_execute(*a, **b)
  File "/home/solarmax/web2py/gluon/dal.py", line 1246, in log_execute
    ret = self.cursor.execute(*a,**b)
DatabaseError: database disk image is malformed
DEBUG:20180:Leaving db_update().
------------------------------------------------------


--------   CODE USED TO WRAP ALL INSERTS AND UPDATES   -------------
def db_insert(table, data):
    """
    Make sure all insert operations go through this routine to
    ensure transactional integrity. Table is a DAL table object,
    data is a dictionary of keyed values.
    """
    ## In web2py, updating to id 0 is an insert operation.
    db_update(table, 0, data)

def db_update(table, record_id, data):
    """
    Make sure all update operations go through this routine to ensure
    transactional integrity.
    Table is a DAL table object,
    record_id is an integer >= 0
    data is a dictionary of keyed values.
    """
    debug("Entering db_update().")
    assert isinstance(table, db.Table)
    assert isinstance(record_id, int) and record_id >= 0
    assert isinstance(data, dict)
    retries = 0
    while True:
        try:
            table[record_id] = data
        except:
            db.rollback()
            if retries > 10:
                raise
            else:
                retries += 1
                warning("db_update() failed. Retrying ...")
                ## Allow interfering process time to complete.
                time.sleep(1)
        else:
            db.commit()
            break
    debug("Leaving db_update().")
-----------------------------------------------------------------

Reply via email to