Re: [sqlite] Tcl - timeout method

2006-08-16 Thread drh
Bud Beacham <[EMAIL PROTECTED]> wrote:
> Thanks.  Now I understand why I was having a problem with errorcode in that 
> situation.
>
>   Are there any other Tcl exceptions to errocode's return value?
> 

The general rules is this:

  If SQLite gives you anything other than SQLITE_OK (or SQLITE_ROW
  or SQLITE_DONE) then you are going to get a TCL exception.

--
D. Richard Hipp   <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Bud Beacham
Thanks.  Now I understand why I was having a problem with errorcode in that 
situation.
   
  Are there any other Tcl exceptions to errocode's return value?

[EMAIL PROTECTED] wrote:
  Bud Beacham wrote:
> Personally, a database being busy does not, in my mind,
> constitute something going wrong. It is expected behaviour,
> and should be handled in a normal manner; i.e. errorcode returns a 5.

Regardless of what it ought to do, this is not was the
TCL interface has ever done in the past. To change it
now would break countless thousands of lines of existing
code. So I think it needs to stay as it is.

--
D. Richard Hipp 


-
To unsubscribe, send email to [EMAIL PROTECTED]
-




Re: [sqlite] Tcl - timeout method

2006-08-16 Thread drh
Bud Beacham <[EMAIL PROTECTED]> wrote:
> Personally, a database being busy does not, in my mind,
> constitute something going wrong.  It is expected behaviour,
> and should be handled in a normal manner; i.e. errorcode returns a 5.

Regardless of what it ought to do, this is not was the
TCL interface has ever done in the past.  To change it
now would break countless thousands of lines of existing
code.  So I think it needs to stay as it is.

--
D. Richard Hipp   <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Bud Beacham


[EMAIL PROTECTED] wrote:  Bud Beacham wrote:
> Yes. This is a bug, but I have not filed it yet. The problem is that the the 
> Tcl errorcode command does not return a 5 (SQLITE_BUSY) when the DB is in 
> use. Instead, Tcl crashes with a "database locked" message. 
> For example,
> sqlite dbCmd $dataBase
> dbCmd timeout 3000
> set qryResult [dbCmd eval $query]
> set errorCode [dbCmd errorcode]
> dbCmd close
> 
> So this means that instead of checking the errorcode to try again on a locked 
> DB you need to enclose everything in a "catch" statement, and check the 
> "catch" for an error.
> 

The current behavior is by design. It is as intented. It is
the "TCL way" to throw an exception when something goes wrong,
and encountering an SQLITE_BUSY error counts as something
going wrong.

That's great if it were documented.  Rather, the documentation implies that 
errorcode should return a 5, and then the program should handle it.  
Personally, a database being busy does not, in my mind, constitute something 
going wrong.  It is expected behaviour, and should be handled in a normal 
manner; i.e. errorcode returns a 5.


Re: [sqlite] Tcl - timeout method

2006-08-16 Thread drh
Bud Beacham <[EMAIL PROTECTED]> wrote:
> Yes.  This is a bug, but I have not filed it yet.  The problem is that the 
> the Tcl errorcode command does not return a 5 (SQLITE_BUSY) when the DB is in 
> use.  Instead, Tcl crashes with a "database locked" message.  
>   For example,
>sqlite dbCmd $dataBase
>  dbCmd timeout 3000
>  set qryResult [dbCmd eval $query]
>  set errorCode [dbCmd errorcode]
>  dbCmd close
>
>   So this means that instead of checking the errorcode to try again on a 
> locked DB you need to enclose everything in a "catch" statement, and check 
> the "catch" for an error.
>   

The current behavior is by design.  It is as intented.  It is
the "TCL way" to throw an exception when something goes wrong,
and encountering an SQLITE_BUSY error counts as something
going wrong.
--
D. Richard Hipp   <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Bud Beacham
Yes.  This is a bug, but I have not filed it yet.  The problem is that the the 
Tcl errorcode command does not return a 5 (SQLITE_BUSY) when the DB is in use.  
Instead, Tcl crashes with a "database locked" message.  
  For example,
   sqlite dbCmd $dataBase
 dbCmd timeout 3000
 set qryResult [dbCmd eval $query]
 set errorCode [dbCmd errorcode]
 dbCmd close
   
  So this means that instead of checking the errorcode to try again on a locked 
DB you need to enclose everything in a "catch" statement, and check the "catch" 
for an error.
  
All said though, I love this DB and the Tcl interface.  I really want to thank 
the author for providing these Tcl APIs since Tcl is the most powerful 
scripting language ever developed.
  
Ulrich Schöbel <[EMAIL PROTECTED]> wrote:
  Hi all,

I'm using sqlite3 inside a Tcl module (mod_websh) of
apache. Everything works fine, except when it comes
to concurrent write accesses.

There's a small transaction where I update two rows.
When I stress the web server it generates a
"database locked" error. I invoke a "db timeout 2000"
just before the transaction, but it doesn't seem to
have any effect.

When I stumbled over this problem I increased the
timeout to 50, which is much longer than the
stress test takes, but the error persists. What's
going wrong here?

Here's a short code snippet:

db timeout 50
db transaction {
set last_acc [lindex [db eval {
select acc_time from last_hit where site = $site and from_ip = $ip
}] 0]
if {![string length $last_acc]} {
db eval {
insert into last_hit values ($site , $ip , $now)
}
set last_acc 0
} else {
db eval {
update last_hit set acc_time = $now where site = $site and from_ip = 
$ip }
}
..
} ;# end of transaction

There's another update inside this transaction, but
it's always the one above that fails.

Maybe the "busy" method is better suited here, but
the docs say nothing about its usage.

Thanks for any help

Ulrich

-
To unsubscribe, send email to [EMAIL PROTECTED]
-




Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Ulrich Schöbel
On Wednesday 16 August 2006 12:55, Christian Nassau wrote:
> Ulrich Schöbel wrote:
> > I thought about that, but I didn't want to include
> > the selects into the locked phase, keeping lock
> > times as short as possible. Shouldn't it work
> > correctly with a deferred lock?
>
> I don't think so: imagine two processes that have succesfully carried
> out their selects (possible, since you've only got a shared lock at that
> point) and now want to proceed to the update:
>
>   SELECT(1) SELECT(2)
>   <-- process 1 here<-- process 2 here
>   UPDATE(1) UPDATE(2)
>
> At this point SQLite cannot allow UPDATE(1) because it might potentially
> invalidate the result of SELECT(2) (and vice versa). So there's no sane
> way through and at least one transaction is forced to error out.
>
>
> ---
>-- To unsubscribe, send email to [EMAIL PROTECTED]
> ---
>--
Yes, sounds plausible. It's obviously the way to go.

Thanks again

Ulrich

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Christian Nassau
Ulrich Schöbel wrote:
> I thought about that, but I didn't want to include
> the selects into the locked phase, keeping lock
> times as short as possible. Shouldn't it work
> correctly with a deferred lock?

I don't think so: imagine two processes that have succesfully carried
out their selects (possible, since you've only got a shared lock at that
point) and now want to proceed to the update:

  SELECT(1) SELECT(2)
  <-- process 1 here<-- process 2 here
  UPDATE(1) UPDATE(2)

At this point SQLite cannot allow UPDATE(1) because it might potentially
invalidate the result of SELECT(2) (and vice versa). So there's no sane
way through and at least one transaction is forced to error out.


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Ulrich Schöbel
On Wednesday 16 August 2006 12:16, [EMAIL PROTECTED] wrote:
> "Christian Nassau" <[EMAIL PROTECTED]> wrote:
> > I would guess that your requests acquire (shared) read locks when the
> > transaction starts and then fail/deadlock when they try to upgrade this
> > to a write lock in your insert/update statement. Maybe it would help to
> > start the transactions with "BEGIN IMMEDIATE" or "BEGIN EXCLUSIVE"...?
>
> In TCL, you can do this as:
>
>db transaction immediate {
>  # code here
>}
>
> --
> D. Richard Hipp   <[EMAIL PROTECTED]>
>
>
> ---
>-- To unsubscribe, send email to [EMAIL PROTECTED]
> ---
>--
Hi Christian, Richard,

I thought about that, but I didn't want to include
the selects into the locked phase, keeping lock
times as short as possible. Shouldn't it work
correctly with a deferred lock?

Nevertheless, I'll give it a try.

Thanks for your help and special thanks to
Richard for sqlite

Ulrich

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread drh
"Christian Nassau" <[EMAIL PROTECTED]> wrote:
> I would guess that your requests acquire (shared) read locks when the
> transaction starts and then fail/deadlock when they try to upgrade this
> to a write lock in your insert/update statement. Maybe it would help to
> start the transactions with "BEGIN IMMEDIATE" or "BEGIN EXCLUSIVE"...?
> 

In TCL, you can do this as:

   db transaction immediate {
 # code here
   }

--
D. Richard Hipp   <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Tcl - timeout method

2006-08-16 Thread Christian Nassau
I would guess that your requests acquire (shared) read locks when the
transaction starts and then fail/deadlock when they try to upgrade this
to a write lock in your insert/update statement. Maybe it would help to
start the transactions with "BEGIN IMMEDIATE" or "BEGIN EXCLUSIVE"...?

Ulrich Schöbel wrote:
> Hi all,
> 
> I'm using sqlite3 inside a Tcl module (mod_websh) of
> apache. Everything works fine, except when it comes
> to concurrent write accesses.
> 
> There's a small transaction where I update two rows.
> When I stress the web server it generates a
> "database locked" error. I invoke a "db timeout 2000"
> just before the transaction, but it doesn't seem to
> have any effect.
> 
> When I stumbled over this problem I increased the
> timeout to 50, which is much longer than the
> stress test takes, but the error persists. What's
> going wrong here?
> 
> Here's a short code snippet:
> 
>   db timeout 50
>   db transaction {
> set last_acc [lindex [db eval {
>   select acc_time from last_hit where site = $site and from_ip = $ip
> }] 0]
> if {![string length $last_acc]} {
>   db eval {
> insert into last_hit values ($site , $ip , $now)
>   }
>   set last_acc 0
> } else {
>   db eval {
> update last_hit set acc_time = $now where site = $site and from_ip = 
> $ip  }
> }
> ..
>   } ;# end of transaction
> 
> There's another update inside this transaction, but
> it's always the one above that fails.
> 
> Maybe the "busy" method is better suited here, but
> the docs say nothing about its usage.
> 
> Thanks for any help
> 
> Ulrich
> 
> -
> To unsubscribe, send email to [EMAIL PROTECTED]
> -
> 


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



[sqlite] Tcl - timeout method

2006-08-16 Thread Ulrich Schöbel
Hi all,

I'm using sqlite3 inside a Tcl module (mod_websh) of
apache. Everything works fine, except when it comes
to concurrent write accesses.

There's a small transaction where I update two rows.
When I stress the web server it generates a
"database locked" error. I invoke a "db timeout 2000"
just before the transaction, but it doesn't seem to
have any effect.

When I stumbled over this problem I increased the
timeout to 50, which is much longer than the
stress test takes, but the error persists. What's
going wrong here?

Here's a short code snippet:

  db timeout 50
  db transaction {
set last_acc [lindex [db eval {
  select acc_time from last_hit where site = $site and from_ip = $ip
}] 0]
if {![string length $last_acc]} {
  db eval {
insert into last_hit values ($site , $ip , $now)
  }
  set last_acc 0
} else {
  db eval {
update last_hit set acc_time = $now where site = $site and from_ip = 
$ip  }
}
..
  } ;# end of transaction

There's another update inside this transaction, but
it's always the one above that fails.

Maybe the "busy" method is better suited here, but
the docs say nothing about its usage.

Thanks for any help

Ulrich

-
To unsubscribe, send email to [EMAIL PROTECTED]
-