场景:
用户提现时,要调用支付宝单笔转账,企业向用户转账。
在对接支付时需要用到回滚,犯的一个错误是先调用支付接口再扣除数据表中的数据。
下面是错误代码:
$arr = MyPdo::instance()->getOne('balance', 'membership', ['uid' => $uid]);
try{
MyPdo::instance()->beginTransaction();
if (!empty($arr)) {
$ret = Transfer::run(Config::ALI_TRANSFER, $aliConfig, $data);
if($ret['msg']=="Success") {
//转账成功要扣除,账户金额
MyPdo::instance()->decValue('membership',$amount,$uid);
$result = ['code' => 0, 'message' => "创建支付宝支付信息成功", 'data' => $ret['order_id']];
show_json($result);
}else{
$result = ['code' => 4001, 'message' => "转账失败", 'data' => false];
show_json($result);
}
}else{
$result = ['code' => 3001, 'message' => "账户余额不足", 'data' => false];
show_json($result);
}
//假如失败
MyPdo::instance()->commit();
}catch (Exception $e){
MyPdo::instance()->rollback();
// $this->returnMessage(2001,$e->errorMessage(),false);
}
正确思路是先检查数据表中是否余额,有余额才能转账给用户,一种报错,一种是修改不成功,这两种都不走commit
正确代码:
$arr = MyPdo::instance()->getOne('balance', 'membership', ['uid' => $uid]);
$message = ['code' => 2001, 'message' => "出现异常", 'data' =>false];
try{
MyPdo::instance()->beginTransaction();
$result=false;
if (!empty($arr)) {
$result=MyPdo::instance()->decValue('membership',$amount,$uid);
if($result) {
//转账成功要扣除,账户金额
$ret = Transfer::run(Config::ALI_TRANSFER, $aliConfig, $data);
$message = ['code' => 1001, 'message' => "创建支付宝支付信息成功", 'data' => $ret['order_id']];
}else{
$message = ['code' => 4001, 'message' => "转账失败", 'data' => false];
}
}else{
$message = ['code' => 3001, 'message' => "账户余额不足", 'data' => false];
}
if($result){
MyPdo::instance()->commit();
}else{
MyPdo::instance()->rollback();
}
}catch (PDOException $e){
MyPdo::instance()->rollback();
//发生错误需要记录日志
return $this->returnMessage(2001,$e->getMessage(),false);
}
return $message;