springboot单机秒杀-aop+锁
一:实现方式
1.aop+锁 (推荐)
2.queue队列
1.之前我们说过,如果锁加在事务里,锁会有问题,建议锁上移,所以本次aop切面为controller层
/** * 并发锁 * * @author jiang */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ThreadLock { /** * 方法名 * * @return */ String method() default ""; }
/** * 锁切面 * * @author jiang */ @Component @Aspect public class LockAspect { /** * 非公平锁 */ private static Lock lock = new ReentrantLock(); @Pointcut("@annotation(club.dandelion.cloud.service.annotion.ThreadLock)") public void lockAspect() { } @Around("lockAspect()") public Object around(ProceedingJoinPoint joinPoint) { Object obj = null; lock.lock(); try { obj = joinPoint.proceed(); } catch (Throwable e) { e.printStackTrace(); } finally { lock.unlock(); } return obj; } }
@GetMapping("/startKill") @ThreadLock() public R startKill(String killId) { return seckillService.startKill(killId); }
@Override @Transactional(rollbackFor = Exception.class) public R startKill(String killId) { Seckill seckill = this.getOne(new LambdaQueryWrapper<Seckill>().eq(Seckill::getSeckillId, killId)); int number = seckill.getNumber(); if (number > 0) { Seckill seckill1 = seckill.setNumber(--number); this.update(seckill1, new LambdaQueryWrapper<Seckill>().eq(Seckill::getSeckillId, seckill.getSeckillId())); SuccessKilled successKilled = new SuccessKilled(); successKilled.setCreateTime(new Date()); successKilled.setSeckillId(Long.parseLong(killId)); successKilled.setState(0); successKilledMapper.insert(successKilled); return R.ok(); } return R.error("没有了!"); }