From a8ff66810b9cc48b60f164b4bca3ce9de4cde08b Mon Sep 17 00:00:00 2001 From: Kenichi Ishigaki Date: Sun, 2 Sep 2012 10:26:40 +0000 Subject: [PATCH] Resolved #56444: updated transaction/locking doc --- Changes | 4 ++-- lib/DBD/SQLite.pm | 42 +++++++++++++++++------------------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/Changes b/Changes index 447453a..da7deec 100644 --- a/Changes +++ b/Changes @@ -3,8 +3,8 @@ Changes for Perl extension DBD-SQLite 1.38_01 to be released *** CHANGES THAT MAY POSSIBLY BREAK YOUR OLD APPLICATIONS *** - Set sqlite_use_immediate_transaction to true by default - (See RT #56444). This usually shouldn't matter, but if you - really need the deferred transaction (which had long been the + to avoid deadlocks (see RT #56444). If you really need + the deferred transaction (which had long been the default), explicitly set sqlite_use_immediate_transaction to false. (ISHIGAKI) diff --git a/lib/DBD/SQLite.pm b/lib/DBD/SQLite.pm index 56f8395..4447624 100644 --- a/lib/DBD/SQLite.pm +++ b/lib/DBD/SQLite.pm @@ -1031,36 +1031,24 @@ statement, and ends by a C or a . =head2 Transaction and Database Locking -Transaction by C or C is nice and handy, but -sometimes you may get an annoying "database is locked" error. -This typically happens when someone begins a transaction, and tries -to write to a database while other person is reading from the -database (in another transaction). You might be surprised but SQLite -doesn't lock a database when you just begin a normal (deferred) -transaction to maximize concurrency. It reserves a lock when you -issue a statement to write, but until you actually try to write -with a C statement, it allows other people to read from -the database. However, reading from the database also requires -C, and that prevents to give you the C -you reserved, thus you get the "database is locked" error, and -other people will get the same error if they try to write afterwards, -as you still have a C lock. C doesn't help -in this case. +The default transaction behavior of SQLite is C, that +means, locks are not acquired until the first read or write +operation, and thus it is possible that another thread or process +could create a separate transaction and write to the database after +the C on the current thread has executed, and eventually +cause a "deadlock". To avoid this, DBD::SQLite internally issues +a C when you begin a transaction by +C or under the C mode (since 1.38_01). -To avoid this, set a transaction type explicitly. You can issue a -C (or C) -for each transaction, or set C -database handle attribute to true (since 1.30_02) to always use -an immediate transaction (even when you simply use C -or turn off the C.). +If you really need to turn off this feature for some reasons, +set C database handle attribute +to false, and the default C transaction will be used. my $dbh = DBI->connect("dbi:SQLite::memory:", "", "", { - sqlite_use_immediate_transaction => 1, + sqlite_use_immediate_transaction => 0, }); -Note that this works only when all of the connections use the same -(non-deferred) transaction. See L -for locking details. +See L for locking details. =head2 C<< $sth->finish >> and Transaction Rollback @@ -1197,6 +1185,10 @@ If you set this to true, DBD::SQLite tries to issue a C (instead of C) when necessary. See above for details. +As of version 1.38_01, this attribute is set to true by default. +If you really need to use C transactions for some reasons, +set this to false explicitly. + =item sqlite_see_if_its_a_number If you set this to true, DBD::SQLite tries to see if the bind values