美文网首页
annotation+aop实现优雅的乐观锁重试

annotation+aop实现优雅的乐观锁重试

作者: EmilioWong | 来源:发表于2019-06-15 23:37 被阅读0次

前言

在spring中,乐观锁重试主要就是在while循环中catch OptimisticLockingFailureException异常,再加上一定的重试限制,这基本是一个模板的代码,写起来不太优雅,而且也是一些重复代码,因此就想如何消除这种模板代码。起初想的是有个callback回调函数包装一下,后来想到了aop,再利用annotation,对annotation做切面,即可实现这模板代码。

talk is cheap,show me the code


// annotation
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OptFailureRetry {

    int retryTimes() default 10;
}


// aop
@Component
@Aspect
public class OptimisticLockingFailureRetryAop implements Ordered {

    @Pointcut("@annotation(com.darcy.leon.demo.annotation.OptFailureRetry)")
    public void retryOnOptFailure() {
    }

    @Around("retryOnOptFailure()")
    public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {

        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        OptFailureRetry annotation = targetMethod.getAnnotation(OptFailureRetry.class);
        int retryTimes = annotation.retryTimes();

        while (true) {
            try {
                return pjp.proceed();
            } catch (OptimisticLockingFailureException e) {
                if (retryTimes > 0) {
                    retryTimes--;
                    System.out.println(Thread.currentThread().getName() + ": optimistic locking failure, remaining retry times:" + retryTimes);
                } else {
                    throw new OverRetryException("retry " + annotation.retryTimes() + " times", e);
                }
            }
        }
    }

//  实现Ordered接口是为了让这个aop增强的执行顺序在事务之前
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

// 重试超限异常
public class OverRetryException extends RuntimeException {

    public OverRetryException(Throwable cause) {
        super(cause);
    }

    public OverRetryException(String message, Throwable cause) {
        super(message, cause);
    }
}

test case

// model
@Data
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;

    @Version
    private Integer version;
}

// dao
@Repository
public interface UserDao extends CrudRepository<User, Integer> {
}

// service
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @OptFailureRetry
    @Transactional
    public void updateWithTransactional() {
        User user = new User();
        user.setUsername("hello aop");
        userDao.save(user);
        System.out.println(userDao.findAll());
        throw new OptimisticLockingFailureException("test roll back");
    }
}
// Test类
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserService userService;

    @Before
    public void setUp() {
        User user = new User();
        user.setUsername("haha");
        userDao.save(user);
    }

    @Test
    public void testUpdateWithTransactional() {
        try {
            userService.updateWithTransactional();
        } catch (OverRetryException e) {
            e.printStackTrace();
        }

        System.out.println("=========================");
        System.out.println(userDao.findAll());
    }
}
执行结果

相关文章

  • annotation+aop实现优雅的乐观锁重试

    前言 在spring中,乐观锁重试主要就是在while循环中catch OptimisticLockingFail...

  • 悲观锁:一个线程得到锁,其它线程挂起,synchronized 乐观锁:一个线程得到锁,其它线程不断重试, cas...

  • 重试利器之Guava Retrying

    目录 重试的使用场景 如何优雅地设计重试实现 guava-retrying基础用法 guava-retrying实...

  • 乐观锁和悲观锁

    参考来源 深入理解乐观锁与悲观锁 乐观锁的一种实现方式——CAS mysql乐观锁总结和实践 乐观锁和悲观锁 悲观...

  • 看完你就知道的乐观锁和悲观锁

    看完你就知道的乐观锁和悲观锁 Java 锁之乐观锁和悲观锁 [TOC] Java 按照锁的实现分为乐观锁和悲观锁,...

  • Spring AOP解决乐观锁重试

    最近在阅读《阿里巴巴Java开发手册》时有这么一段内容: 【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么...

  • Java锁:悲观/乐观/阻塞/自旋/公平锁/,CAS,Reent

    JAVA LOCK [TOC] 一、广义分类:乐观锁/悲观锁 1.1 乐观锁的实现CAS (Compare and...

  • 并发参数

    悲观锁与乐观锁 悲观锁 synchronized和ReentrantLock等独占锁就是悲观锁思想的实现乐观锁一般...

  • MySQL之乐观锁·MVCC

    一、 乐观锁 和 悲观锁 乐观锁 和 悲观锁 是实现并发操作的两种不同的 加锁思想,其中: 乐观锁 假设:操作能成...

  • 表锁和行锁

    MySQL中的锁总体可以分为悲观锁和乐观锁。悲观锁MySQL中有自带的锁。乐观锁需要自己写程序控制来实现乐观锁的功...

网友评论

      本文标题:annotation+aop实现优雅的乐观锁重试

      本文链接:https://www.haomeiwen.com/subject/alaifctx.html