[DC-185] The pessimistic offline locking manager locks the entire table Created: 04/Nov/09  Updated: 13/Dec/12

Status: Reopened
Project: Doctrine 1
Component/s: None
Affects Version/s: 1.1.4, 1.1.5, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Fabian Brussa Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 7
Labels: None
Environment:

Windows XP, WampServer Version 2.0


Attachments: File DC185TestCase.php     Text File row_based_locking.patch    

 Description   

Scenario:
$entity = Doctrine::getTable('Steps')->find($pID);
$lockingManager = new Doctrine_Locking_Manager_Pessimistic( Doctrine_Manager::connection() );
$lockingManager->releaseAgedLocks(300);
$gotLock = $lockingManager->getLock($entity, 'user1' );

Running this code locks the entire table "Steps", and not just the record.

in the table "doctrine_lock_tracking", in the fields: "object_type" and "object_key" are saved in this case: "Steps" and "IDStep".
I think that here must be saved "Steps" and "120" (the value of IDStep).



 Comments   
Comment by Fabian Brussa [ 18/Nov/09 ]

Is anybody looking into this issue ?

Comment by Jonathan H. Wage [ 18/Nov/09 ]

Can you provide a test case that shows the issue? It is hard to look into the issue without a test to run When I look at the code and our tests everything is passing and fine so I am not sure what your issue could be. Re-open if you have more information to provide.

Comment by Fabian Brussa [ 19/Nov/09 ]

ok, I attach the test case

Comment by Fabian Brussa [ 03/Dec/09 ]

Have you already been able to look at the testcase ??

Comment by Fabian Brussa [ 14/Jan/10 ]

Any news ??

Comment by Piotr Leszczyński [ 25/Jun/10 ]

This issue is still valid for Doctrine 1.2. Doctrine_Locking_Manager_Pessimistic is UNUSABLE without this bug fixed!

Comment by Markus Wößner [ 02/Jul/10 ]

Having a look at "Doctrine_Locking_Manager_Pessimistic::getLock()" it becomes clear what causes this misbehaviour:

    public function getLock(Doctrine_Record $record, $userIdent)
    {
        $objectType = $record->getTable()->getComponentName();
        $key        = $record->getTable()->getIdentifier();

        $gotLock = false;
        $time = time();

        if (is_array($key)) {
            // Composite key
            $key = implode('|', $key);
        }

        try {
            $dbh = $this->conn->getDbh();
            $this->conn->beginTransaction();

            $stmt = $dbh->prepare('INSERT INTO ' . $this->_lockTable
                                  . ' (object_type, object_key, user_ident, timestamp_obtained)'
                                  . ' VALUES (:object_type, :object_key, :user_ident, :ts_obtained)');

            $stmt->bindParam(':object_type', $objectType);
            $stmt->bindParam(':object_key', $key);
            $stmt->bindParam(':user_ident', $userIdent);
            $stmt->bindParam(':ts_obtained', $time);

There is NO hint about the Record's identifier VALUE but only about the identifier's NAME (mostly "id") which appears to be redundant information. Instead of ...

        $key = $record->getTable()->getIdentifier();

..there should be something like ..

        $key = $record->get($record->getTable()->getIdentifier());

In case of composite keys a string concatenation, prefixed by identifier's name might work but I would recommend using "md5()" on resulting value to limit its length since field "object_key" is limited to 250 chars.

Comment by Florian Zumkeller-Quast [ 02/Jul/10 ]

Based on the previous comment by Markus Wößner i created a patch for row based locking.

It concatenates the PK fields and their values to a string and calculates the sha-1 hash as a unique string representing that record. This string is then used as key so that we'll only lock the single Record and not the whole table.

I hope you'll give this patch a try - It solved this problem for me.

Comment by Markus Wößner [ 02/Jul/10 ]

I applied patch from Mr. Florian Zumkeller-Quast and provided testcase didn't fail anymore. I think this should do it. By the way I find it strange that this issue isn't already fixed. I guess locking is not very much used by Doctrine users.

Comment by Jérôme Weber [ 21/Nov/11 ]

I applied patch too and it works now. I guess too that nobody use Lockings but when you use it ... without the patch it fails.

Comment by Grégoire Paris [ 13/Dec/12 ]

Duplicate of http://www.doctrine-project.org/jira/browse/DC-984

Generated at Wed Apr 23 11:30:52 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.