Laravel & MySQL 优惠券使用后可重复领取逻辑

更新日期: 2017-12-21 阅读次数: 8210 分类: Laravel

原设计

一个用户对同一优惠券领取一次,即使使用了,也无法重复领取

  • coupon_id, user_id 做了联合唯一索引
  • state 代表是否已经使用: 0 为未使用; 1 为已使用

但这样的表设计,不能支持同一优惠券使用后再次领取。

解决方案

利用 MySQL unique 允许多个 null 的存在的特性。参考 MySQL 唯一约束 Unique 是否允许存在多个 NULL 值

  • coupon_id, user_id, available 做联合唯一索引
  • available 替代 state 字段作为优惠券是否可用的标识: 1 代表可用;NULL 代表不可用。这样做的目的是为了让 NULL 具有可读性。

这样就可以保证数据库不会重复插入,即,用户不会瞬间同时领取同一优惠券。

Laravel 中处理 unique 异常

local.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '7-996-1' for key 'unique_cid_uid'

try {
	$user_coupon->save();
} catch (\Illuminate\Database\QueryException $e){
	$errorCode = $e->errorInfo[1];
	if($errorCode == 1062){
		$rsp['err_code'] = Error::DUPLICATE;
		$rsp['err_msg'] = '不能重复领取同一优惠券';
	}
}

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式