1、背景
1.1 业务背景
本案例为线上环境真实案例,业务背景是商户领取优惠券,商户领取了优惠券后会往mysql表中插入一条领用记录,假设这张优惠券可以被商户领取多张,第一次领取时,记录是insert一条已领取量=1的记录,当再次领取这张优惠券时,则是update这条记录已领取量=2的操作。
1.2 简化后的表结构
字段 | 含义 |
id | 主键ID |
coupon_id | 优惠券ID |
user_id | 商户ID |
received_num | 已领数量 |
1.3 表索引
除了主键索引外,还额外设置了user_id和coupon_id的联合唯一索引;
1.4 代码逻辑
当时设置唯一索引的目的是为了防止同一个user_id并发领取同一个coupon_id时insert成多条记录。有了唯一索引后,并发领取时,先执行的insert会成功;后执行的insert会抛唯一键冲突,然后再update。
try {
//插入
insert into tableX (user_id,coupon_id,received_num) values (?,?,?);
} catch (DuplicateKeyException e) {
//唯一键冲突后,更新
u