一人一单
需求:修改秒杀业务,要求同一个优惠券,一个用户只能抢一张
加锁(悲观锁) 使用synchronize,给用户id加锁。
注意用intern()方法,因为toString返回的新的对象,intern是从常量池取。
事务要想生效,是因为Spring对方法进行了动态代理,而this.createVoucherOrder不是代理对象
synchronized (userId.toString().intern()) { IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy(); //拿到接口代理 return proxy.createVoucherOrder(voucherId); //拿到代理对象,代理对象会自动开启事务 //return this.createVoucherOrder(voucherId); //这种拿到的是目标对象,不是代理对象。所以代理会失效 }
唯一索引,确保每个用户对同一优惠券只能有一条记录。