简体   繁体   中英

MySQL and PHP: Using SELECT FOR UPDATE

I am trying to acquire a row-level lock for a table in a database that prevents any future sessions from reading that row until the lock is released.

To accomplish this, I've been trying to use the SELECT ... FOR UPDATE syntax on an indexed column, but I can't seem to prevent other sessions from reading that row when they use the exact same query.

Is there something more I need to do? I'm using MySQL 5.5, PHP 7, and the table in question is Innodb.

To elaborate, the flow is thus:

START TRANSACTION;
SELECT id FROM tbl WHERE id = 1 FOR UPDATE;
... (PHP stuffs)
UPDATE tbl SET value = 'xyz' WHERE id = 1;
COMMIT TRANSACTION;

Subsequent requests will also run the exact same lines of code, but I would like one request to block the others from starting until it's committed the transaction.

Have you looked in the MySql docs about the InnoDB lock types?

https://dev.mysql.com/doc/refman/5.5/en/innodb-locking.html

For some unknown reasons I could not get the SELECT FOR UPDATE to work well with my codes (still trying though) but meanwhile, I had to implement my own lock on an innoDB table. The issue was avoidance of transaction balances mix-ups for a payment gateway I am developing. The following pseudo code can help anyone looking for an alternative transaction locks .

//Add transaction lock flag column into your table
//TXN_LOCK; Defaulted to Integer 0;

//FIRST: Select the balance and current txn-lock value  
$stopCount = 1;
$dbBalance = $tnxLock = 0;
$failureFlag = false; 
do {
    //run the select query; get values including $dbBalance and $tnxLock 
    //increment the counter; we won't run this forever          
    $stopCount++;
    if($stopCount > 3){
        //only a few trials
        $failureFlag = true;
        break;
    }
    //lock table, it looks free
    if($tnxLock == '0'){
        //update table set tnxLock = 1;         
    }
}while ($tnxLock > 0);  

if($failureFlag){
    //log and end; return failure   
    return false;
}else {
    //proceed 
}   
//--------------------------------

//now do you mathematics 
//add or subtract value from the balance

//then update the table; at the same time update the lock-code back to zero 
//UPDATE table set balance = xxx, tnxLock = 0;

//NOTE: This can be set as a function, 
//   with right params and flags of doing both credits and debits and 
//   called each time such operation is needed for consistency
//   Normal begin and commit transaction can also be added for more stability

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM