匿名函数与回调函数

#事务回滚的回调函数
##在usercontroller里面写一个方法


1.防止出现异常而导致数据不完整性调用TransactionService这个控制器里面的handle方法

TransactionService::handle(function () use ($data) {
            foreach ($data as $item) {
                ProgramLabelService::edit(['weight' => $item['weight']], $item['program_label_id']);
            }
        });

2.接下来我们去TransactionService看看怎么处理 注意 Closure一定写上去
 static public function handle(Closure $handle) {
    DB::beginTransaction();
    $result = null;
    try {
        $result = $handle();
        DB::commit();
    } catch (Exception $exception) {
        DB::rollBack();
        throw $exception;
    }
    return $result;
} 

3.把函数当作参数传递到这方法里面用$handle接收,这里面的方法从头运行一直运行到赋值的地方$result = $handle();
才开始运行传递过来的方法

复杂的匿名函数

1.在提交的方法里面调用distributedLockTemplate一直运行到调用的地方然后相当于把这一块代码放到distributedLockTemplate方法去运行
    到哪里开始运行就看接参数的位置在哪里
2.运行的顺序 先在submit里面运行一直运行到开始调用的地方然后去到distributedLockTemplate方法,方法从头开始运行一直运行到出参数的位置
开始运行调用的代码
 public function submit(Request $request)
{
    $request->validate([
        'resource_id' => 'required',
        'activity_id' => 'required',
        'order_detail_id' => 'required',
    ]);
    $all = $request->all();

    RedisService::distributedLockTemplate("tongKeYiGouSubmit:{$all['order_detail_id']}", function () use ($all) {

        $orderDetail = OrderDetailService::getByPrimaryKeyOfUser($all['order_detail_id']);
        $resource = ResourceModel::query()->find($all['resource_id']);
        if ($resource->type != ResourceService::TYPE_TON_KE_YI_GOU) throw new BusinessException('资源类型错误');

        // 查询是否存在
        $tongKeYiGou = TongKeYiGouService::get([
            'resource_id' => $all['resource_id'],
            'activity_id' => $all['activity_id'],
            'order_detail_id' => $all['order_detail_id']
        ]);
        if ($tongKeYiGou) {
            // 存在则更新
            TongKeYiGouService::edit($all, $tongKeYiGou->tong_ke_yi_gou_id);
        } else {
            TransactionService::handle(function () use ($all, $orderDetail) {
                // 不存在则创建
                TongKeYiGouService::create($all);
                // 更新进度
                RecordStudyProgressService::record($orderDetail, 100, $all['resource_id'], $all['activity_id']);
            });
        }
    });
    return $this->success();
}

————————

在RedisService里面

 static public function distributedLockTemplate(string $key, Closure $handle, $type = self::LOCK_TYPE_THROW_EXCEPTION)
{
    // 锁有效时长
    $time = 5;
    // 存入随机数,防止业务代码超时释放锁出错
    $random = GUIDService::getGuid();
    // 获取锁
    $count = self::setExNx($key, $random, $time);
    // 记录返回值
    $result = null;
    // 如果获取到锁
    if ($count) {
        // 执行业务代码
        try {
            //这里开始运行调过来的代码
            $result = $handle();

        } catch (Exception $exception) {
            throw $exception;
        } finally {
            self::releaseLock($key, $random);
        }
    } else {
        if ($type == self::LOCK_TYPE_THROW_EXCEPTION) {
            throw new BusinessException('操作太快,请稍后重试');
        } else if ($type == self::LOCK_TYPE_RECURSION) {
            sleep(0.2);
            // 递归调用
            $result = self::distributedLockTemplate($key, $handle, $type);
        } else {
            throw new BusinessException('参数错误');
        }
    }

    return $result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值