在做抽奖项目的时候,有时需要限定奖品的数量,如果单独通过查询数据库统计奖品的数量,并发的时候会出现超出的问题,我们可以使用ThinkPHP6的事务锁来防止超出,Db::startTrans() 和 Db::commit() 以及 Db::rollback(),一个是开启事务锁,一个是提交事务,另一个是回滚事务,以下是个例子。
<?php declare (strict_types = 1); namespace app\api\controller; use think\facade\Db; use app\Request; use think\facade\View; class Luck{ public function add(Request $request){ $data=$request->param(); $data['created_at'] = time(); // 获取奖品数量限制 $prize_limits = [ 'PHP' => 2, 'JAVA' => 10, 'Python' => 6 ]; $awards = $data['awards']; // 开始事务,锁定相关数据 Db::startTrans(); try { // 锁定奖品数量表,避免并发冲突 $macCount = Db::name('choujiang')->where(['awards' => $awards])->lock(true)->count(); // 检查奖品数量是否超出 if (isset($prize_limits[$awards]) && $macCount >= $prize_limits[$awards]) { Db::rollback(); // 回滚事务 return returnJson('5001', "$awards 抽奖已经超出"); } // 锁定奖品数量表,避免个数超出 $macCount = Db::name('choujiang')->where(array('shareStatus'=>0))->lock(true)->count(); // 检查奖品数量是否超出 if ($macCount >= 18) { Db::rollback(); // 回滚事务 return returnJson('5001', "抽奖已经结束!"); } $res = Db::name('choujiang')->insert($data); if($res){ Db::commit(); // 提交事务 return returnJson('200','抽奖成功'); }else{ Db::rollback(); // 回滚事务 return returnJson('500','网络异常,抽奖失败'); } }catch (\Exception $exception){ // dd($exception); Db::rollback(); // 回滚事务 return returnJson('500','1网络异常,抽奖失败'); } } }
文章评论(0)