At 2010-09-02 01:04, Aryeh Gregor wrote:
On Wed, Sep 1, 2010 at 6:47 PM,
Platonides<Platonides(a)gmail.com> wrote:
Is there some way to find out those points were
the commit needs to be
there for lock freeing and not just for normal transaction finish ?
Look at every
single commit() and guess? Alternatively, we could just
assume none of them are for releasing locks, skip them and see what
Domas comments out to fix the site when it breaks. ;)
Maybe this could be done step by step by adding named transactions and
some other other method/parameter like commitToUnlockTables so the
developers using it would know what it is used for ;-). Commit (in
general) is obviously not always done to simply unlock tables. Some
might not expect changes be committed already and might want to rollback
but they would be unable to.
So until proper handling of transactions would be implemented warnings
might be thrown if begin/commit would not be called without proper
attributes. An additional warning might be thrown if more then say... 3
nested transactions would be started as it would probably mean locking
too many tables.
This approach would catch this:
begin transaction outer_tran
update tbl1 set name='1234' --locks tbl1
begin transaction inner_tran
update tbl2 set name='1234' -- locks tbl2
begin transaction inner_inner_tran -- -> throw warning: too many
open tran
update tbl3 set name='1234' -- locks tbl3
commit transaction inner_inner_tran
commit transaction inner_tran
commit transaction outer_tran
But then again it wouldn't catch this:
begin transaction outer_tran
update tbl1 set name='1234' --locks tbl1
begin transaction inner_tran
update tbl2 set name='1234' -- locks tbl2
commit transaction inner_tran
begin transaction other_inner_tran
update tbl3 set name='1234' -- locks tbl3, but no warning is
thrown (and yes, MSSQL keeps tbl2 locked too)
commit transaction other_inner_tran
commit transaction outer_tran
And so (with the exception of installation and upgrade process) warnings
might be thrown when you actually run to many inserts/updates after most
outer transaction was started. Something like this would work I think:
if ($this->trxLevel()>0 && $this->isWriteQuery( $sql ))
{
$this->mNumWritesSinceTran++;// set to 0 on tran end
if ($this->mNumWritesSinceTran>TOO_MANY_WRITES_SINCE_TRAN)
{
wfWarn( "Too many writes since most outer transaction started
({$this->mNumWritesSinceTran}). Avoid locking tables when possible." );
}
}
Regards,
Nux.