spring 事务隔离级别导致的bug
事情是这样的,ios进货单有一个数量加一手,减一手的功能,每加减一次就会异步调用后台的接口,后台判断sku如果不存在就插入,存在就更新。
问题描述:
当ios发了多次请求后,
在第二次请求的时候,第一次请求插入的sku程序里查不出来
但是数据库里能查出来
后来仔细研究了下,发现这就是所谓的不可重复读情况。
在applicationContext.xml配置文件中的事务相关模块把事务隔离级别提成到SERIALIZABLE。
<!-- 进货单加减一手方法存在不可重复读情况,提升事务隔离级别 -->
<tx:method name="changeShoppingCartSkuList" propagation="REQUIRED" isolation="SERIALIZABLE" rollback-for="Exception" />
问题又来了:
args:
skuIds[]=122890,122891,122892,122893,122894
timeid=4152
orderId=2733
num=1
sign=c30fc44b4a7681fbc19bd9c8c2de2237
authTime=2016-09-10 16:18:17
authId=900000000000140
exception:
org.springframework.dao.DeadlockLoserDataAccessException:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may exist in com/itonghui/biz/shoppingcart/dao/mapper/OrderListSkuMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select * from order_list_sku t where t.sku_id = ? and order_id = ?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:263)
会出现死锁现象,在方法前面加上synchronized同步解决问题。
总结一下,关于异步调用不可重复读问题解决方案:
1.在applicationContext.xml配置文件中的事务相关模块把事务隔离级别提成到SERIALIZABLE。
2.在方法前面加上synchronized同步