Mybatis插入多条相同记录
来源:互联网 发布:零基础学算法pdf 编辑:程序博客网 时间:2024/06/05 20:12
最近发现生产上的项目出现,插入多条相同记录的问题,排查了很长时间,最终确认是事务的原因。
项目结构是原来JDBC+springMVC改的Mybatis+SpringMVC。
Service层逻辑设计如下:
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT) public class Service(){ public void insertOrUpdate(Entity e){ Entity s = search(e); if(s!=null) update(e); else insert(e); } }
在并发插入记录时,就会出现插入多条记录的情况,后将隔离级别改为Isolation.SERIALIZABLE,问题不再复现。
但是却在日志中多了如下异常:
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
引起上述原因是由于多个事务占用了一个row的排他锁,导致死锁产生。A和B两事务都访问同一条的数据,都没有找到,这时两个事务都会在这个row上增加排他锁。A在插入数据时,发现有其他事务占用该行,就等待;B在插入数据时,发现其他数据在进行插入,就抛出上述异常,释放掉自己的排他锁;A插入数据。
给事务块加同步锁可以解决上面的问题。
为了避免上述异常,还需要从事务上进行解决,因为数据库采用的是mysql 的innodb,支持行级锁,所以使用select * from table where keyId = ${id} for update锁定插入行,此时锁定自动增长主键,然后根据返回结果进行插入还是更新操作。这样既解决了插入多条数据的问题,也避免了事务串行化导致数据锁定频繁导致deadlock的问题。
备注:代码事务级别的控制,有时候还会出问题,所以简单的处理方式是在插入表中设置唯一索引,这样就不会有重复数据了。
0 0
- Mybatis插入多条相同记录
- mybatis插入多条记录
- 一次向数据库中插入多条相同记录的SQL方法(只有一个列不同)
- 一次插入多条记录
- 一次插入多条记录
- 一次性插入多条记录
- mysql插入多条记录
- SQL 插入多条记录
- MySQL插入多条记录
- php插入多条记录
- 关于Mybatis一次性插入多条数据返回的记录数的问题
- MyBatis 3 批量插入多条数据
- mysql 快速插入(insert)多条记录
- 向表中插入多条记录
- access事务插入多条记录
- 一次插入多条记录 [mysql]
- SQL 一次插入多条记录 例句
- Oracle 插入多条记录的sql
- 将整型数据转换为string类型
- Java的值传递
- spring调用存储过程
- c++ builder使用过程中,记录的bug
- [LeetCode303] Range Sum Query - Immutable
- Mybatis插入多条相同记录
- cocos2d游戏接入admob,解决,@import GoogleMobileAds 错误的方法
- plsql 连接不上 登陆不了 tnsnames.ora 问题
- 把Eclipse项目迁移到AndroidStudio
- App Store 评分 跳转 代码
- 固定table的表头
- QT中的QRegExp学习(正则表达式)
- Expecting a string, date or number here, Expression x is instead a freemarker.template.TemplateBoole
- Java枚举