On Tue, Nov 10, 2009 at 06:04:20PM -0500, Frank Chang scratched on the wall:
> 
>      We have an application which uses Microsoft SQL Server 2005 
> Extended stored procedures in conjunction with Sqlite databases. 
> We have a C++ DLL which uses the following code to insert rows
> into a SQLite database:
> 
> sprintf(Command,"INSERT INTO [Keys] ([Key], [Cluster], "
> "[DupeGroup]) VALUES (\"%s\", \"%*.*s\", %d)",
> MCKey,BlockSize,BlockSize,MCKey,DupeGroup);

  Aside: using string functions to build query strings is a Bad Idea,
  and string constants in SQL use single-quotes, not double.


>     When we run this UPDATE statement from two SQL Server 2005 Management 
> Studio clients concurrently, one of the client processes returns with
> the error code Database is locked and the other client process is
> suspended. Has anyone seen this problem?

  If you keep getting SQLITE_BUSY return codes sooner or later you're
  obligated too cancel the current statement and rollback any open
  transactions.

  See:   http://sqlite.org/c3ref/busy_handler.html

  In specific:

     The presence of a busy handler does not guarantee that it will be
     invoked when there is lock contention. If SQLite determines that
     invoking the busy handler could result in a deadlock, it will go
     ahead and return SQLITE_BUSY or SQLITE_IOERR_BLOCKED instead of
     invoking the busy handler. Consider a scenario where one process
     is holding a read lock that it is trying to promote to a reserved
     lock and a second process is holding a reserved lock that it is
     trying to promote to an exclusive lock. The first process cannot
     proceed because it is blocked by the second and the second process
     cannot proceed because it is blocked by the first. If both
     processes invoke the busy handlers, neither will make any
     progress. Therefore, SQLite returns SQLITE_BUSY for the first
     process, hoping that this will induce the first process to release
     its read lock and allow the second process to proceed.

  You're basically implementing a manual busy handler with your loop.
  Sooner or later it needs to give up and start over or things can
  remain locked.  If all you're doing is waiting, you might want to
  look at sqlite3_busy_timeout():

  http://sqlite.org/c3ref/busy_timeout.html

  This will keep trying if things still look safe, but will return
  SQLITE_BUSY right away if SQLite detects a possible deadlock.

   -j

-- 
Jay A. Kreibich < J A Y  @  K R E I B I.C H >

"Our opponent is an alien starship packed with atomic bombs.  We have
 a protractor."   "I'll go home and see if I can scrounge up a ruler
 and a piece of string."  --from Anathem by Neal Stephenson
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to