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
- mysql锁(行锁,表锁)同一用户同一秒操作保持唯一性
- 乐观锁(两个以上用户不能同时进行同一操作)
- 同一用户不同终端登录限制(附:同一浏览器不同用户登录解决方案)
- mysql 同一表複製數據
- android 保持同一Session网络请求
- 文字和img保持在同一水平线
- MySQL 中对于同一表的两种操作
- 防止同一用户同时登陆
- .net防止同一用户登陆
- 防止同一用户同时登陆
- 防止同一用户同时登陆
- 防止同一用户同时登陆
- 防止同一用户重复登录
- 防止同一用户同时登录
- java同一用户登录问题
- 防止同一用户同时登陆
- 禁止同一用户同时登录
- 防止同一用户同时登录
- SPDIF 色差输出 视频输出 S-Video YUV YCbCr YPbPr RGB VGA WXGA 分别的详细介绍 视频方式接口简介
- TCP三次握手与四次挥手
- IOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem
- Ubuntu12.04搭建Android开发环境
- android音频处理
- mysql锁(行锁,表锁)同一用户同一秒操作保持唯一性
- C++:与C在函数库上的丝丝缕缕记录
- Java Servlet API 2.5/3.0的官方下载
- IOS开发中的CGFloat、CGPoint、CGSize和CGRect
- Winsock编程流程
- java https连接以及乱码问题解决办法
- Linux设备驱动程序学习(14)-Linux设备模型(各环节的整合)
- windows 7 下 android 手机通过 usb-wifi 共享笔记本 本地连接 上网
- 多线程的自旋锁