mysql锁机制 php_千万级高并发请求处理之mysql数据乐观锁及php代码实现

悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念。本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍。

悲观锁

悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。

这里需要注意的一点是不同的数据库对select for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描。

乐观锁

乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。

1. SELECT data AS old_data, version AS old_version FROM …;

//根据获取的数据进行业务操作,得到new_data和new_version

. UPDATE SET data = new_data, version = new_version WHERE version = old_version

if (updated row > 0) {

// 乐观锁获取成功,操作完成

} else {

// 乐观锁获取失败,回滚并重试

}

乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放

php代码实现乐观锁实例:

$doctor = $_GET['doctor_id'];//接受医生的UID

$number = $_GET['number'];//排班编号

mysql_query("begin");//开启MYSQL 事务

$number =5;//定义查询次数,避免出现死循环

while(True && ++$i)

{

if($i

{

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;

如果有更换的方法。请多多指教,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值