mysql锁(行锁,表锁)同一用户同一秒操作保持唯一性

来源:互联网 发布:ip core网络什么意思 编辑:程序博客网 时间:2024/06/05 05:29

今天mysql群里一群友询问,同一用户同一秒只可以有一行数据insert入库,否则是update。表面上看起来很简单,用个判断语句就行了,先查询表是否已经存在,但其实不然。

原文:

【冒泡】小宝他爸@上海2014/4/3 14:31:10用户再同一秒做了两个请求,都正常入库了【冒泡】小宝他爸@上海2014/4/3 14:31:42但是我还在同一秒只能一个入库,另一个就拒绝【冒泡】小宝他爸@上海2014/4/3 14:32:05但是我是想在同一秒只能一个入库,另一个就拒绝

if($db->getone("select id from log where  user_id='1' and date_create='".date("Y-m-d 00:00:00")."'")){$db->query("UPDATE log SET hits = hits+1 WHERE user_id='1' and date_create='".date("Y-m-d 00:00:00")."'");}else{$db->insert('log_user_count', array('hits' => 1, 'user_id'=>1, 'date_create'=>date("Y-m-d 00:00:00")));}

表面上看代码是没有问题的,这个逻辑应该可以。但细看会发现,如果2个并发过来时,还没来得及insert操作,都在select层面上,所以结果都是false,2个同时去执行了insert

后来经过讨论,还是用mysql加锁来保持数据一致性,表锁?行锁,还没定。具体没测试,应该可行。

(用事务应该也行!)


//执行SQL语句 锁掉stat_num表 $sql = "LOCK TABLES stat_num WRITE"; //表的WRITE锁定,阻塞其他所有mysql查询进程 $DatabaseHandler->exeCute($sql); //执行更新或写入操作 $sql = "UPDATE stat_num SET `correct_num`=`correct_num`+1 WHERE stat_date='{$cur_date}'"; $DatabaseHandler->exeCute($sql); //当前请求的所有写操作做完后,执行解锁sql语句 $sql = "UNLOCK TABLES"; $DatabaseHandler->exeCute($sql); 


上面方法可能不行!!!!!

这个东东,好像还是比较麻烦的。

一般最简单的办法是字段加唯一索引。否则的话就用复杂一点方法。

1、用生成文件方法

2、用memcache方法(转自http://ju.outofmemory.cn/entry/48924)

<?php/** * 使用Memcache实现给进程加锁的类 * * Copyright (C) 2013 JeffJing * * 一些时候需要让系统的某些操作串行化,这个时候就要对这些操作来加上一把锁。 好比你去上厕所, 你要先推厕所门看能否进去,进去的话上锁,其他人就进不来了, 等你拉完粑粑之后把锁打开,这样的话就保证了厕所永远只有1个人, 上厕所的过程是串行化的, 同时只有1个人上。 * 网上的一些解决方案大多是使用文件的, 我就纳闷了,加锁的时候创建一个文件, 解锁的时候把文件删掉。 * 我就纳闷: Why not memcached ? 顺手写了这么一个 , 希望对大家"拉粑粑"的这种操作有所帮助 * * 举个栗子: * $key = '厕锁'; * if(MemLock::addLoack($key)) { * //拉粑粑喽,pu~pu~~~~~ * MemLock::releaseLock($key); * } else { * //不好意思, 厕所有人啦!! * } * * http://www.phpv5.com */class MemLock {private static $memcache = null;/** * 获取memcached连接 * * @return Memcached */public static function getConnection() {if (! isset ( self::$memcache )) {self::$memcache = new Memcache ();self::$memcache->connect ( '127.0.0.1', 11211 );}return self::$memcache;}/** * 加锁 * * @param $key 锁关键字 * * @return boolean true 成功获取到锁 false 获取锁失败 */public static function addLock($key) {$memcache = self::getConnection ();//不存在的话,先创建空值$v = $memcache->get ( $key );if ($v === false) {$memcache->set ( $key, 0 );}$index = $memcache->increment ( $key, 1 );if ($index == 1) {return true;}return false;}/** * 释放锁 * * @param $key 锁关键字 * * @return boolean true 释放成功 false 释放失败 */public static function releaseLock($key) {$memcache = self::getConnection ();return $memcache->delete ( $key );}}





0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 已经参加工作想学个本科证怎么办 火车晚点耽误下一趟列车怎么办 门外装监控没有预留电线怎么办 框架柱主筋柱顶预留长度不够怎么办 遇到很嚣张的人怎么办 在地板砖上铺木地板卧室门怎么办 宝宝打预防针的本子丢了怎么办 宝宝打预防针本子丢了怎么办 打疫苗的本子丢了怎么办 麦客收割机麦秸里加麦粒怎么办 高铁乘务员身高不够怎么办 坐火车买到站票怎么办 买上车补票原票怎么办? 买的商务座补票怎么办 12306账号被别人登录怎么办 飞机不提供餐食怎么办 12306退票支付宝失败怎么办 12306重复支付怎么办支付宝 支付宝登的12306账号怎么办 没买儿童高铁票怎么办 网上订的机票怎么办托运 半夜买高铁票不出票怎么办 轻轨少买了一站怎么办 高铁火车票丢了怎么办 如果高铁票丢了怎么办 高铁票丢了怎么办 报销 高铁如果没赶上怎么办 高铁管家待核验怎么办 动车没有票了怎么办 12306取消订单3次怎么办 【12306取消订单3次怎么办】 火车票取消订单3次怎么办 12306收不到验证码怎么办 安逸花验证码次数限制怎么办 航班晚点导致错过转机怎么办 想去沈阳站送站怎么办 高铁没有赶上车怎么办 火车晚点赶不上下一趟车怎么办 列车晚点影响下一趟车怎么办? 高铁晚点赶不上下班车怎么办 火车在半路坏了怎么办