I figured it out, I was NOT calling sqlite3_finalize(stmt) in the
initial call to setDefaultIsInSlideShow() which was read only, so the
table still had a read lock on it, so the read/write always failed.
On Sun, Mar 7, 2010 at 3:36 PM, Sam Carleton wrote:
> My use of SQLite is within a Apache module and Axis2/C web services.
> Every request invokes a unique call to sqlite3_open_v2, most of the
> time there are multiple calls to sqlite3_open_v2 in one request. For
> example the module part, which sends configuration to the web servers
> calls sqlite3_open_v2 as read only to initialize the web service, it
> closes the connection prior to the web service being called. Next the
> web service will open up the database in either read/write or read,
> depending on what it is doing.
>
>
>
> I am using my first transaction, which I think it working fine, except
> I am getting some strange behavior with a call that is made
> immediately after the transaction.
>
> (This client is a test harness designed exclusively to test web
> services, no other clients are running and only in instance of the
> Apache process is running. I am able to change the order quickly and
> easily, and this order is not indicative to the order things will
> normally be called in.)
>
>
> 1: Client calls the web server method setDefaultIsInSlideShow () as to
> have it return the current state, aka read only.
> 2: The client calls the method enableSlideShow() which creates and
> commits the transaction all in one call, code to follow.
> 3: The client calls setDefaultIsInSlideShow() again, this time to set
> the value. It is this time the sqlite3_step() returns SQLITE_BUSY,
> EVERY time.
>
> When I move #3 into the #1 spot, it works fine. What is really
> strange is even when I removed the BEGIN TRANSACTION/COMMIT
> TRANSACTION, I continued to get the error when #3 is #3. So at this
> point I really don't know what the issue might be. Oh, another
> strange fact, the two databases are DIFFERENT files. The transaction
> happens in the event database, the other call acts on the system
> database. Since I am totally stumped, I am posting the code as
> complete as I can make it: It is broken up into a number of different
> functions in my code, but I will try to consolidate it as much as
> possible while not leaving out details:
>
> /** #2: enableSlideShow */
>
> #define SQL_SET_ISINSLIDESHOW_CUSTOMER \
> "UPDATE Customer SET IsInSlideShow = ?2 WHERE CustomerId = ?1"
>
> #define SQL_SET_ISINSLIDESHOW_NOT_CUSTOMER
> "UPDATE Customer SET IsInSlideShow = ?2 WHERE CustomerId <> ?1"
>
> enableSlideShow()
> {
> // Make note this is a different database file then the call below
> int rc = sqlite3_open_v2(pCfg->pszEventDB, ,
> SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, zVfs);
> rc = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);
>
> rc = UpdateSlideShowTable(env, db,
> SQL_CMD(SQL_SET_ISINSLIDESHOW_NOT_CUSTOMER), nCustomerId,
> AXIS2_FALSE);
> if( rc == SQLITE_OK) rc = UpdateSlideShowTable(env, db,
> SQL_CMD(SQL_SET_ISINSLIDESHOW_CUSTOMER), nCustomerId, AXIS2_TRUE);
>
> if( rc == SQLITE_OK)
> rc = sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL);
> else
> rc = sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
> NULL);
>
> sqlite3_close(db);
> }
>
>
>
> static int UpdateSlideShowTable(const axutil_env_t *env, sqlite3 *db,
> const char *zSql, int nByte, int nCustomerId, axis2_bool_t bEnable)
> {
> adb_imageDTO_t* pImageDTO = NULL;
> sqlite3_stmt *stmt = NULL;
> const char* pzTail = NULL;
>
> int rc = sqlite3_prepare_v2(db, zSql, nByte, , );
> if( rc == SQLITE_OK) rc = sqlite3_bind_int( stmt, 1, nCustomerId);
> if( rc == SQLITE_OK) rc = sqlite3_bind_int( stmt, 2, bEnable ==
> AXIS2_FALSE ? 0 : 1);
> if( rc == SQLITE_OK) rc = sqlite3_step(stmt);
>
> sqlite3_finalize(stmt);
> if(rc == SQLITE_DONE)
> return SQLITE_OK;
> return rc;
> }
>
> /** #3: setDefaultIsInSlideShow() that is a reader/writer */
>
> #define SQL_INSERT_DEFAULTISINSLIDESHOW \
> "UPDATE DBLookup SET ItemValue = ?1 WHERE Category = 'SystemSettings'
> AND ItemName = 'DefaultIsInSlideShow'"
>
> setDefaultIsInSlideShow()
> {
> // Make know that this is a different database file then the call above
> int rc = sqlite3_open_v2(pCfg->pszSystemDBFile, ,
> SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, NULL);
> sqlite3_stmt *stmt = NULL;
> const char* pzTail = NULL;
>
> rc = sqlite3_prepare_v2(db, SQL_CMD(SQL_INSERT_DEFAULTISINSLIDESHOW),
> , );
> if( rc == SQLITE_OK) rc = sqlite3_bind_int( stmt, 1, bValue ==
> AXIS2_FALSE ? 0 : 1);
> if( rc == SQLITE_OK) rc = sqlite3_step(stmt); // *** This returns
> SQLITE_BUSY every time it is called AFTER the transaction above,
> whether or not the