我正在开发一个记录存储系统,将扫描的、索引的和加密的记录存储在物理盒子中。
我有一个名为"getAvailablePlace()“的方法,它检查哪个盒子和哪个seq可供存储。我想锁定此方法。也就是说,当一个用户进入这种方法时,他得到了box:12序列:55作为空的place..simultaneously,同时另一个用户访问相同的方法,他也可能得到相同的values..box:12序列:55,这是容易出错的。
那么,当一个用户已经进入此进程时,我是否可以锁定此方法?
我使用的是SQLite、wamp和codeigniter。
发布于 2011-08-11 19:54:28
我正在使用下面的代码:
define('LOCK_FILE', "/path/to/your/lockfile-".$argv[1].".lock");
if( isLocked() ) die("ALREADY RUNNING !!!!\n" );
function isLocked()
{
# If lock file exists, check if stale. If exists and is not stale, return TRUE
# Else, create lock file and return FALSE.
if( file_exists( LOCK_FILE ) )
{
# check if it's stale
$lockingPID = trim( file_get_contents( LOCK_FILE ) );
# Get all active PIDs.
$pids = explode( "\n", trim( `ps -e | awk '{print $1}'` ) );
# If PID is still active, return true
if( in_array( $lockingPID, $pids ) ) return true;
# Lock-file is stale, so kill it. Then move on to re-creating it.
echo "Removing stale lock file.\n";
unlink( LOCK_FILE );
}
file_put_contents( LOCK_FILE, getmypid() . "\n" );
return false;
} 您可以更改它,以不检查pid,只使用该文件作为锁定信息。
发布于 2011-08-11 19:07:47
这里有一个通用的方法:使用另一个表来存储当前被“锁定”的盒子。然后展开"getAvailablePlace()“以在生成下一个盒子id之前检查锁定的盒子。生成box id后,将其写入锁表。所有这三个操作都必须在数据库事务中进行。
另一种解决方案是在数据库中对每个盒子的序列号进行计数。如果你在一个事务中执行"get biggest for box y,add1 to it,write it back“这样的操作,你应该没问题。
发布于 2011-08-11 19:08:49
你不能在PHP中做到这一点,因为每个用户都会收到自己的“运行时”。但是你可以通过一些外部的方法来实现,比如数据库中的locks表。因此,您函数将检查表中是否存在某些记录,如果存在,则跳过/返回false或其他任何内容,如果不存在,则运行受保护的代码。
请注意,您必须实现double-checking才能获得真正无错误的代码。
https://stackoverflow.com/questions/7024624
复制相似问题