您的位置:首页 > 数据库 > Redis

运用laravel,redis,mysql事务,进行红包金额随机发放的思路详解

2019-01-23 14:36 686 查看

运用laravel,redis,mysql事务,进行红包金额随机发放的思路详解

1.redis的原子性

好好的利用redis的原子性可以很好的实现很多,不好实现的事,如,秒杀商品时,之后我的另一篇博客会详细给你们讲讲利用redis实现简单的秒杀功能的小例子。而redis的原子性即:rpop函数。在你们看我这边博客之前,你们可以先去了解一些redis相关的函数运用,对看下面的例子有很大帮助。

2.mysql的事务操作

下面我会运用到事务有关的知识,不管是php原生的事务写法,还是php的任何框架,思想都是一样:要么一起成功,要么一起失败!事务就是这么任性,哈哈。开玩笑。但思想就是这么回事。虽然每个框架的写法不一样,但是万变不离其宗,就是这个道理。这里我为什么会用到事务呢,是因为在用户成功领取红包后,涉及到两个步骤:用户余额的变动,用户订单记录的增加。两者必须保持一致性。在抢红包的过程中,一旦用户较多,和服务器相关的影响,可能会出现意想不到的问题,这时,如果出现问题,事务就很好的控制到了一致性。不会出现一个用户余额加了,但记录却没有他的信息,这就尴尬了。所以才会采用事务。

好了,废话不多说,上代码看看,因为该代码放置于laravel框架中,所以有些写法遵循于laravel框架的写法,但思想都是一致的,有用的可以参考参考,也不枉我辛辛苦苦写那么久~~,☺

代码在这里呢~~~~

/** 实现随机红包
* @param $sum 红包总金额
* @param $count 红包个数
* @return array
*/
public function moneyRound( sum,sum,sum,count )
{
$arr = [];
$hes = 0;
hess=0;for(hess =0; for (hess=0;for(i=0;i&lt;i&lt;i<count;$i++){
$rand =rand(1,1000);
arr[]=arr[]=arr[]=rand;
hes+=hes+=hes+=rand;
}
arr2=[];foreach(arr2 =[]; foreach (arr2=[];foreach(arr as key=&gt;key=&gt;key=>value){
round=round((round = round((round=round((value/hes)∗hes)*hes)∗sum,2);
arr2[]=arr2[] =arr2[]=round;
hess+=hess+=hess+=round;
}
if(sum!=round(sum !=round(sum!=round(hess,2)){
hesss=round(hesss =round(hesss=round(sum-$hess,2);
arr2[0]=arr2[0]=arr2[0]=arr2[0]+$hesss;
}
return $arr2;
}

/*
生成红包并存入redis中,
以便红包发放时取
只需在访问前执行一次
*/
public function packetRedis()
{
Redis::del( $this->packetKey );
$packetRedis = this−&gt;moneyRound(this-&gt;moneyRound(this−>moneyRound(this->money, this−&gt;num);for(this-&gt;num ); for (this−>num);for(i=0; $i < count( $packetRedis ) ; $i++) {
Redis::lpush( $this->packetKey, packetRedis[packetRedis[packetRedis[i] );
}
if ( Redis::llen( $this->packetKey ) == $this->num ) {
echo “

红包生成成功,可以抢红包啦!

”;
}
}

/*
数据处理操作
*/
public function qrcodeAct(Request $request)
{
//判断该扫码用户是否已存在于会员表
$MemberUid = Members::where( “openid”, wuchatUser[′id′])−&gt;value(&quot;uid&quot;);if(!wuchatUser[&#x27;id&#x27;] )-&gt;value(&quot;uid&quot;); if ( !wuchatUser[′id′])−>value("uid");if(!MemberUid ) {
MemberData=[′name′=&gt;FILTEREMOJI(MemberData = [ &#x27;name&#x27; =&gt; FILTEREMOJI(MemberData=[′name′=>FILTEREMOJI(wuchatUser[‘name’]),
‘nickname’ => FILTEREMOJI($wuchatUser[‘nickname’]),
‘openid’ => $wuchatUser[‘id’],
‘avatar’ => $wuchatUser[‘avatar’],
‘referrer’ => $this->uid,
‘sex’ => $wuchatUser[‘original’][‘sex’],
‘enroll_time’ => time(),
‘sign_in’ => time(),
];
$MemberUid = MemberModel−&gt;addmember(MemberModel-&gt;add_member(MemberModel−>addm​ember(MemberData);
}
//判断该用户是否已经领取了红包
$packetRecode = RecordTransaction::where( [‘openid’ => $wuchatUser[‘id’], ‘uid’ => $MemberUid ] )->first();
if ( $packetRecode ) {
exit(“

你已经抢过了哟,给别人一次机会嘛!

”);
}
//重点在这里,上面可以不看,主要是思想思想!!!!
//从redis红包集合中rpop第一个红包金额元素
$packetOne = Redis::rpop( this−&gt;packetKey);if(!this-&gt;packetKey ); if ( !this−>packetKey);if(!packetOne ) {
exit(“

来慢了,红包已经被抢光了!

”);
}
//执行事务进行会员余额的增加,订单记录的增加
DB::beginTransaction();
try {
//执行会员余额的增加
$balanceAdd = Members::where( [‘openid’ => $wuchatUser[‘id’], ‘uid’ => $MemberUid ] )->increment( “credit1”, $packetOne );
if ( $balanceAdd ) {
//执行订单记录的添加
$RecordTransaction = new RecordTransaction();
$orderData = [
‘uid’ => $MemberUid,
‘ordersn’ => ORDER_SN(),
‘money’ => $packetOne,
‘type’ => 3,
‘time’ => time(),
‘explain’ => ‘红包领取’,
‘openid’ => wuchatUser[′id′],′remark′=&gt;′红包:+′.+wuchatUser[&#x27;id&#x27;], &#x27;remark&#x27; =&gt; &#x27;红包:+&#x27;.+wuchatUser[′id′],′remark′=>′红包:+′.+packetOne,
‘trend’ => 1
];
$transactionOrderId = RecordTransaction−&gt;addtransaction(RecordTransaction-&gt;add_transaction(RecordTransaction−>addt​ransaction(orderData);
if( $transactionOrderId ){
DB::commit();
return redirect( ‘/shop/member/user/index?k=’.rand(100,9999) );
}else {
DB::rollback();
exit(“

新增订单记录失败!

”);
}
} else {
DB::rollBack();
exit(“

余额增加失败!

”);
}
} catch (Exception $e) {
// 出错回滚数据
DB::rollBack();
exit(“

抢取红包失败,请稍后再试!

”);
}
}

好了,代码就这些,不明白的可以找我,附上上面代码的定义的几个属性,待参考:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: