我使用的脚本在两个数据库之间同步数据(本地到托管域)。当有人从CMS注销时,我进行了同步。不幸的是,我已经看到两次注销发生得足够接近以至于同步脚本执行两次的情况。它不是我试图改变的系统的一部分,但我期待一种简单的方法来使该脚本(sync.php)在它已经运行时不执行。
我想出了测试脚本:
$db = new DB_Mysql();
if ( $db->transactionBegun() == "0" )
{
$_Continue = true;
$_Continue = $_Continue && $db->squery( "START TRANSACTION" );
$_Continue = $_Continue && $db->squery( "SET @TransactionBegun = true" );
sleep( 10 );
$_Continue = $_Continue && $db->squery( "INSERT INTO tbConfiguration VALUES( NOW(), NOW() )" );
$_Continue = $_Continue && $db->squery( "SET @TransactionBegun = false" );
if ( $_Continue )
{
$db->query( "COMMIT" );
} else {
$db->query( "ROLLBACK" );
}
}
transactionBegun方法包括:
function transactionBegun()
{
$_ResultSet = $this->query("SELECT @TransactionBegun AS TransactionBegun")->fetch_all(true);
return $_ResultSet[ 'TransactionBegun' ];
}
对于一些奇怪的外星人原因,我可以两次(同时)运行该脚本,并且两个条目都将被输入。
任何想法??
修改
我忘了提到我使用mysql_pconnect()
并且服务器托管在Windows机器上。整个系统是使用平板电脑的收银机。访问服务器的唯一客户端是“localhost”。
答案 0 :(得分:1)
变量是每个连接,而不是每个用户。使用两个独立的脚本,您将拥有两个独立的独立连接,每个连接都有自己的可变空间。
如果您需要真正处理锁定并行使用,则需要使用通过GET_LOCK()
获取的服务器端锁,或使用对资源执行独占锁定的事务模式。
答案 1 :(得分:1)
使用基于文件的锁。
当脚本开始时,请检查“sync_db.lock”之类的文件。如果存在,则运行另一个脚本实例。此时,您可以选择睡眠几秒钟并重新开始,或者只是放弃。
如果它不存在,请创建该文件并完成数据库事务。交易完成后,只需删除该文件即可。
要避免线程失败的问题,请将当前时间戳写入文件。当脚本检查文件时,请读取其内容并查看是否已经过了给定的时间段。如果脚本继续执行事务,请不要忘记覆盖时间戳。
答案 2 :(得分:0)
一个小伪代码: 检查文件(/var/tmp/.trans.lck)是否存在 如果是退出 如果没有,创建锁定文件 完成后删除锁定文件