PHP 锁定与并发脚本运行

问题描述 投票:0回答:1

我使用自己的PHP函数来锁定一些脚本和MySQL表数据,以避免脚本多次运行时多次修改或插入数据。

功能很简单,只需将 MySQL 行从 0 更新为 1,准备好后将 1 更新为 0。

我的脚本总是在开始时检查这个值,如果它是 1,它就会等待,或者退出(这取决于情况)。

这个方法就像一个魅力,除了一种情况:如果两个脚本恰好在同一时间启动,它会比其他查询晚更新该行,但它仍然返回 0,因此它们执行两次工作,这会导致数据库不一致。这种情况很少发生,但那一次却引起了巨大的骚动。

我使用这个解决方案而不是flock(),因为我还必须独立于PHP脚本来保护MySQL表。

我该怎么办? TIA

我的两个主要功能:

function check( $menu ){
    global $Db;
    $lock = mysqli_query( $Db, "SELECT COUNT(*) AS c FROM lock WHERE $menu='1' AND date >= NOW() - INTERVAL 12 SECOND;" );
    $lockData = mysqli_fetch_object( $lock );
    mysqli_free_result( $lock );
    if ( $lockData->c > 0 ) return true; else return false;
}

function lock( $menu, $state ){
    global $Db;
    if ( $state == '1' ) $query = "UPDATE lock SET $menu='$state', date=NOW()"; else $query = "UPDATE lock SET $menu='$state'";
    mysqli_query( $Db, $query );
}
php mysql locking
1个回答
0
投票

不要使用MySQL的“事务”来锁定超过几秒钟。它不是为此而设计的,并且可能会导致严重的挂起。 (是的,对于短案例来说,FOR UPDATE

可能是必要的。)

GET_LOCK()

 及其朋友是 MySQL 中更简单的替代方案。

最有效的是使用文件系统锁。请务必将其放在

/tmp

中,以便在崩溃后它会自动消失。

© www.soinside.com 2019 - 2024. All rights reserved.