开发者社区> 问答> 正文

快速多次请求接口,事务失效,造成数据重复:报错

我有一个报名接口:在service里判断此用户在报名表里没有记录就会插入一条。

但是如果前端快速请求两次,就会因为第一次请求没来得及插入的时候第二次已经执行select了,造成数据重复。

我想知道的是:为什么我在service里加上事务了 (mysql数据库,默认的不可重复读) 那为什么在并发下还是会读取到一个事务没有提交的数据。(请您帮我解释一下为什么,而不是告诉我别的解决方案)

 

展开
收起
kun坤 2020-06-07 22:27:01 1072 0
1 条回答
写回答
取消 提交回答
  • 在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力(搬运自https://www.cnblogs.com/catmelo/p/8878961.html)

    ######

    可重复读是指在同一个事务内的查询都是事务开始时刻一致,但你说了你是快速提交了两次请求,那就是两个事务。

    ######

    1. 前端限制重复提交数据

    2. 数据库设置唯一索引,保证不插入重复数据

    ######

    查询的时候没加锁。

    ######

    那为什么在并发下还是会读取到一个事务没有提交的数据

    你描述的场景难道不是在并发下,一个事务没有读取到另外一个事务没有提交的数据吗?

    还是我没get到你的点

     

    ######

    这个业务不能按你这样操作···· 首先表上加唯一索引····然后代码请做幂等操作····你的逻辑查不到就查入····并发的时候是控制不了的·····你这个方法如果上线 其实就是靠天吃饭······

    ######

    服务端代码加锁吧。

    2020-06-07 22:27:06
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
面向失败设计 立即下载
事务、全局索引、透明分布式 立即下载
低代码开发师(初级)实战教程 立即下载