> That's true, but the comment is a bit deceptive, In this
> particular case SQLite is supposed to invoke the busy-handler. What
> should happen is that SQLite grabs the SHARED lock then fails to get
> the RESERVED. But in this case SQLite is smart enough to know that
> it can release the SHARED lock, invoke the busy-handler, then try
> again.

I'm glad it is so.
BTW, this special case (with your great examples) as long as all cases
when busy handler is invoked/not invoked are better to be mentioned
somewhere in here http://www.sqlite.org/lockingv3.html or here
http://www.sqlite.org/c3ref/busy_handler.html.

Pavel

On Mon, Nov 23, 2009 at 10:17 AM, Dan Kennedy <danielk1...@gmail.com> wrote:
>
> On Nov 23, 2009, at 9:26 PM, Pavel Ivanov wrote:
>
>> According to SQLite sources:
>>
>> ** The pager invokes the busy-handler if sqlite3OsLock() returns
>> ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
>> ** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
>> ** lock. It does *not* invoke the busy handler when upgrading from
>> ** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
>> ** (which occurs during hot-journal rollback). Summary:
>> **
>> **   Transition                        | Invokes xBusyHandler
>> **   --------------------------------------------------------
>> **   NO_LOCK       -> SHARED_LOCK      | Yes
>> **   SHARED_LOCK   -> RESERVED_LOCK    | No
>> **   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
>> **   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
>>
>>
>> When you issue BEGIN IMMEDIATE statement SQLite has first obtain
>> SHARED lock and right after that RESERVED lock too.
>
> That's true, but the comment is a bit deceptive, In this
> particular case SQLite is supposed to invoke the busy-handler. What
> should happen is that SQLite grabs the SHARED lock then fails to get
> the RESERVED. But in this case SQLite is smart enough to know that
> it can release the SHARED lock, invoke the busy-handler, then try
> again. This is different from the situation where the connection
> already has a SHARED lock and tries to upgrade to reserved after
> the user has read from the db.
>
> For example, assuming that some other process has a RESERVED lock
> on our file:
>
>   INSERT INTO ...             /* busy-handler invoked */
>
>   BEGIN IMMEDIATE;            /* busy-handler invoked */
>
>   BEGIN;
>   INSERT INTO ...             /* busy-handler invoked */
>
> but if we try:
>
>   BEGIN;
>   SELECT * FROM ...           /* Grab SHARED lock */
>   INSERT INTO ...             /* Immediate SQLITE_BUSY */
>
> The last case is different as SQLite cannot release the SHARED lock
> before calling the busy-handler (doing so might mean the transaction
> does not appear isolated to the user). So it cannot call the
> busy-handler without risking deadlock. Return immediately instead.
>
> I'm not sure why the OP's call is returning immediately without calling
> the busy-handler.
>
> Dan.
>
>
>
>
>
>
>
>
>
>
>
>> In your, Tom,
>> situation obtaining of the SHARED lock will succeed right away unless
>> proc A has already written something to disk but RESERVED lock will
>> fail and no busy handler is called here.
>>
>> Besides that I cannot say what thoughts are behind this design
>> solution.
>>
>>
>> Pavel
>>
>> On Mon, Nov 23, 2009 at 9:15 AM, O'Neill, Owen <oone...@averyberkel.com
>> > wrote:
>>>
>>>
>>> Hi Tom,
>>>
>>> Whilst not knowing much about the process, I have a recollection
>>> about
>>> something in the documentation that said if sqlite thought that there
>>> was a potential for deadlock the busy handler was never even called.
>>>
>>> Could that explain this ?
>>>
>>> Cheers
>>> Owen
>>>
>>>
>>>
>>> -----Original Message-----
>>> From: sqlite-users-boun...@sqlite.org
>>> [mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Tom Broadbent
>>> Sent: Friday, November 20, 2009 7:27 PM
>>> To: sqlite-users@sqlite.org
>>> Subject: [sqlite] begin transaction
>>>
>>> i have several processes all trying to write to a given DB.  i have
>>> set
>>> sqlite3_busy_timeout to 10000 (10 sec).  when proc A successfully
>>> beings
>>> a trasaction IMMEDIATE what appears to happen when proc B attempts to
>>> begin transaction IMMEDIATE is that it fails immediately w/
>>> SQLITE_BUSY.
>>> i would expect that proc B would wait 10 sec trying to begin
>>> transaction
>>> rather than fail immediately.
>>>
>>> is this expected?
>>>
>>> thanks
>>> tom
>>>
>>> ______________________________________________________________________
>>> This email has been scanned by the MessageLabs Email Security System.
>>> For more information please visit http://www.messagelabs.com/email
>>> ______________________________________________________________________
>>> _______________________________________________
>>> sqlite-users mailing list
>>> sqlite-users@sqlite.org
>>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>>> _______________________________________________
>>> sqlite-users mailing list
>>> sqlite-users@sqlite.org
>>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>>>
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users@sqlite.org
>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to