我有一个报名接口:在service里判断此用户在报名表里没有记录就会插入一条。
但是如果前端快速请求两次,就会因为第一次请求没来得及插入的时候第二次已经执行select了,造成数据重复。
我想知道的是:为什么我在service里加上事务了 (mysql数据库,默认的不可重复读) 那为什么在并发下还是会读取到一个事务没有提交的数据。(请您帮我解释一下为什么,而不是告诉我别的解决方案)
在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力(搬运自https://www.cnblogs.com/catmelo/p/8878961.html)
######可重复读是指在同一个事务内的查询都是事务开始时刻一致,但你说了你是快速提交了两次请求,那就是两个事务。
######1. 前端限制重复提交数据
2. 数据库设置唯一索引,保证不插入重复数据
######查询的时候没加锁。
######那为什么在并发下还是会读取到一个事务没有提交的数据
你描述的场景难道不是在并发下,一个事务没有读取到另外一个事务没有提交的数据吗?
还是我没get到你的点
######
这个业务不能按你这样操作···· 首先表上加唯一索引····然后代码请做幂等操作····你的逻辑查不到就查入····并发的时候是控制不了的·····你这个方法如果上线 其实就是靠天吃饭······
######服务端代码加锁吧。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。