发锁事务重试机制(JPA高并发下的乐观锁异常)总结,以及中间遇到各种问题和解决方案
2016-03-07 15:13
871 查看
接入ping++支付,账户余额的数据安全问题,使用jpa乐观锁+AOP重试机制
乐观锁:<span style="white-space:pre"> </span>model实体类加version字段
<span style="white-space:pre"> </span>private Integer version=0; //jpa乐观锁 @Version @Column(name = "version") public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; }
---修改实体时,
<span style="white-space:pre"> </span>tradeBAccount.setVersion(tradeBAccount.getVersion()+1);//乐观锁<span style="white-space:pre"> </span>tradeBAccountDao.save(tradeBAccount);
参考:
并发锁事务重试机制(JPA高并发下的乐观锁异常)
我的博文中,有一篇短文Java结合Junit做并发测试用例,是介绍JPA在高并发下,多个Service方法更新同一个记录;在异常信息中有StaleObjectStateException和ObjectOptimisticLockingFailureException异常信息。有些业务这种靠JPA维护的版本信息是可行的,如果两个不同用户同事(高并发)购买一件马丁靴鞋子,最后会更新该马丁靴在库数量,如果没有重试机制,肯定只有一个用户购买失败;可能这没有什么,用户再次提交购买就ok了;可是作为事逼可能成就人生的工程师,你一定不能容忍,于是有了重试机制。1:解决方案定义Aspectj拦截器,指定方法发生乐观锁异常时,进行重试。2:show coding.(1) 因为不是所有方法发生乐观锁异常都是需要重试机制的,所以需要先定义切面接口定义IsTryAgainJava代码/*** 自定义尝试切面接口*/@Retention(RetentionPolicy.RUNTIME)public @interface IsTryAgain {// marker annotation}(2)Service接口方法加上切面接口定义Java代码/*** 并发乐观锁需要重试的方法*/@IsTryAgainboolean TryAgainMethod() throws Exception;(3)定义Aspectj切面拦截器定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。Java代码@Aspectpublic class SystemArchitecture {@Pointcut("execution(* myapp..service..*(..))")public void businessService() {}}Java代码@Aspectclass ConcurrentOperationExecutor implements Ordered {private static final int DEFAULT_MAX_RETRIES = 2;private int maxRetries = DEFAULT_MAX_RETRIES;private int order = 1;public void setMaxRetries(int maxRetries) {this.maxRetries = maxRetries;}public int getOrder() {return this.order;}@Around("myapp.SystemArchitecture.businessService()")public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {int numAttempts = 0;PessimisticLockingFailureException lockFailureException;do {numAttempts++;try {return pjp.proceed();}catch(PessimisticLockingFailureException ex) {lockFailureException = ex;}}while(numAttempts <= this.maxRetries);throw lockFailureException;}}3:更多AOP知识,Spring AOP和Aspectj的知识。相关文章推荐
- spring中H2数据库的使用
- Python 模块(八) socketserver 以及 线程、进程
- 数据库中多对多关系及其实现
- MS lync
- javascript call()和apply()
- webapp前端开发软键盘与position:fixed为我们带来的不便
- Android总结02_Touch事件的分发与消费机制
- baidumapsdk: Authentication Error errorcode: 230 msg: APP Scode码校验失败
- Centos配置国内yum源
- 一个单机棋盘式半即时解谜RPG的开发与反思、3
- nginx密码认证
- Linux 终端命令
- Python基础学习教程-第1讲 python语言介绍
- Binary Tree Zigzag Level Order Traversal 【Java】
- Android性能优化之如何避免Overdraw
- 115.View the Exhibit and examine the structure of the CUSTOMERS table.
- JS代码片段:日期格式化
- 软件工程个人作业02
- 设计模式之组合模式
- Nginx VS HaProxy