PHP-PHP 并发处理,只需要往数据库插入一条数据,但是请求量很大,总是插入许多条,用memcache锁效果不明显

发布于 2017-05-31 14:44:01 字数 516 浏览 1254 评论 3

    static function recordTest(){
$cacheLock = new CacheLock();//封装的memcache
if($cacheLock->getLock('key')){
return false;
}
$cacheLock->setLock('key');
$uid = 'test';
//去数据库查询是否存在
$recordItem = RecordItem::getWithUid($uid);
if($recordItem->createTime){
return false;
}
/**
* 执行插入部分
*/
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑾兮 2017-09-14 23:58:14

使用 cas 和 casbykey 来做判断

瑾兮 2017-07-30 00:45:40

我也遇到過類似的問題。最終找到的解決方案只能是使用 InnoDB 引擎,以使用行級鎖來在增加數據時進行鎖定。對於搶佔鎖和死鎖,我沒遇到有問題反饋,但數據也有髒數據的產生,但是可以接受的少量的。

 function throw_err($msg) {
throw new Exception($msg);
}
mysql_query("START TRANSACTION");
try {
$sql = "SELECT * FROM table_name WHERE id=1 FOR UPDATE"; // 獲取更新鎖
$result = mysql_query($sql) or throw_err(mysql_error());
$rs = mysql_fetch_assoc($result);
mysql_query("UPDATE table_name SET `modified`='".date('Y-m-d H:i:s')."' WHERE id={$rs['id']}") or throw_err(mysql_error()); // 使其他線程進入鎖等待

// 業務邏輯
...

mysql_query("COMMIT"); // 提交數據並釋放鎖
} catch (Exception $e) {
mysql_query("ROLLBACK"); // 回滾並釋放鎖
// print_r($e->getMessage());
}

如果其他朋友有更好的方法,歡迎分享。

虐人心 2017-06-12 16:59:37

不清楚你的getLock()是什么样的语义,所以下面都是猜的。

我看有分开的getLock()和setLock(),我猜setLock()是上锁,getLock()返回真表示已经上锁,但是这是个错误的锁的实现。在最初没上锁的时候,并发时多个请求中getLock()返回真,就会多次进入到setLock()以及后面数据库查询和插入的代码。

正确的做法是用Memcache::add()来实现锁,add()返回假的时候表示键已经存在。不经封装看起来是这样的:

static function recordTest(){
$memc = memcache_connect("localhost", 8129);
if (!$memc->add($key, 1, FALSE, 30)) {
return false;
}
// 去数据库查询是否存在
// 执行插入部分
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文