情况说明 :
最近供应商转账这个操作,偶尔会出现重复提现的情况:当然微信转账一次,本地系统余额扣了两次,导致供应商余额为负数
分析:
这种情况开始这是一次并发,因为实际重复扣钱的那两笔的确是同一时间插入的,但是用户余额也相应的减少,这样一来,这是一起重复提交数据的操作,form表单重复提交这种情况也是有的,但是我不想从前端控制,基本没有办法,就决定使用mysql事务从后台限制一下;
解决:直接上代码:测试成功的重点是开启MySQL严格模式和用户金额字段设置为无符号以及表结构是InnoDB
$db->query('set sql_mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"'); //开启MySQL严格模式
$db->query('START TRANSACTION'); //开启事务
/* 更新数据表 */
$sql = "UPDATE " . $ecs->table('suppliers_account') . " SET " .
"admin_note = '$admin_note', " .
"is_paid = '$is_paid'," .
"admin_user = '$admin_user'," .
"paid_time = '$paid_time'" .
"WHERE id = '$id'";
$res = $db->query($sql);
// 更新提现记录
if (!$res) {
$db->query("ROLLBACK"); //事务回滚
sys_msg('更新失敗1');
}
if ($is_paid == 1) {
$change_desc = '提现';
$change_type = 99;
$change_money = (-1) * $amount;
$r = log_supp_account_change($suppliers_id, $change_money, 0, 0, 0, $change_desc, $change_type);
if (!$r) {
$db->query("ROLLBACK"); //事务回滚
sys_msg('更新失败2');
}
}
$db->query("COMMIT"); //提交事务
后续思考:如何处理事务并发,事务并发问题和处理方式