造成并发的原因:有一个叫张三专家很火爆的,假设张三在这周三上午9点到10点之间有问诊排班,系统后台会生成本周三9点到10点的10个专家号,等待患者来定号,但张三太火爆了,结果有1 万个患者定票
假设数据库设计
uid(张三) time(时间) number(排班编号)
当一个请求过来的时候张三医生的排班号就会减一,这里流程假设有一万个请求同时请求张三医生的排班号,每个请求就会开辟一个进程,就会有一万个进程同时争夺张三医生的排班号,由于操作系统CPU 在不断的切换,等待,唤醒,。。。。(具体可以去了解多线程编程)。这样会造成多进程安全问题。
这时候就要添加乐观锁解决问题,在数据库表添加 verison (版本号)(accord)
id uid time number(排班编号) version (版本号) status(状态)
1 张三 9:00-9:10 z-0001 001 0
2 张三 9:10-9:20 z-001 002 0
......
php 代码:
<?php
$doctor = $_GET['doctor_id'];//接受医生的UID
$number = $_GET['number'];//排班编号
mysql_query("begin");//开启MYSQL 事务
$number =5;//定义查询次数,避免出现死循环
while(True && ++$i)
{
if($i<$num)
{
try{
$sql = "select version,id,number from accord where uid=".$doctor." and status=0 limit 1";
//假设$database_obj->query($sql);就直接执行SQL语句
//这个时候我们拿到了张三医生的排班号,假设这里拿到了id 为1的号
$data = $database_obj->query($sql);
coding........
当你的业务逻辑做完后要更新id 为1排班号状态的时候
$sql = "update accord set status=1 where version=".$data['version']." and id=".$data['id'];
$data = $database_object->query($sql);
if(FALSE==$data)
{
throw new Exception();//抛出异常
}
//如果成功就提交
mysql_query('commit');
关键:这个时候由于是并发数据请求,CPU 做不停的切换,进程在执行到这里的时候操作系统的执行权交给其他的进程,当前进程就处于等待状态,id 为一的排班状态被修改占用,SQL 语句执行失败
}catch(Exception $e)
{
mysql_query('rollback');
}
mysql_query('end');
}
break;
?>
以上就是乐观锁的原理,但根据自己的业务需要可以做如下改动,个人认为乐观锁并不是处理并发数据最好的方法。下面会介绍列队的方式
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。