At 2010-09-02 01:04, Aryeh Gregor wrote:
On Wed, Sep 1, 2010 at 6:47 PM, PlatonidesPlatonides@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.