1
0
Fork 0
mirror of https://github.com/DBD-SQLite/DBD-SQLite synced 2025-06-07 14:19:10 -04:00

Resolved #56444: updated transaction/locking doc

This commit is contained in:
Kenichi Ishigaki 2012-09-02 10:26:40 +00:00
parent 24c782bd5f
commit a8ff66810b
2 changed files with 19 additions and 27 deletions

View file

@ -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)

View file

@ -1031,36 +1031,24 @@ statement, and ends by a C<COMMIT> or a <ROLLBACK>.
=head2 Transaction and Database Locking
Transaction by C<AutoCommit> or C<begin_work> 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<commit> statement, it allows other people to read from
the database. However, reading from the database also requires
C<shared lock>, and that prevents to give you the C<exclusive lock>
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<pending> lock. C<busy_timeout> doesn't help
in this case.
The default transaction behavior of SQLite is C<deferred>, 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<BEGIN> on the current thread has executed, and eventually
cause a "deadlock". To avoid this, DBD::SQLite internally issues
a C<BEGIN IMMEDIATE> when you begin a transaction by
C<begin_work> or under the C<AutoCommit> mode (since 1.38_01).
To avoid this, set a transaction type explicitly. You can issue a
C<begin immediate transaction> (or C<begin exclusive transaction>)
for each transaction, or set C<sqlite_use_immediate_transaction>
database handle attribute to true (since 1.30_02) to always use
an immediate transaction (even when you simply use C<begin_work>
or turn off the C<AutoCommit>.).
If you really need to turn off this feature for some reasons,
set C<sqlite_use_immediate_transaction> database handle attribute
to false, and the default C<deferred> 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<http://sqlite.org/lockingv3.html>
for locking details.
See L<http://sqlite.org/lockingv3.html> 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<begin
immediate transaction> (instead of C<begin transaction>) 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<deferred> 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