打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于数据库层面上锁,解决程序并发插入多条重复数据

公司的app新版本上线,其中有一个摇一摇的功能,由于安卓端没有做好处理,导致在同一时间数据post提交了2次。在后台判断发现并没有插入的数据,然后啪啪啪一下子插入了2条。也就是在插入前没有判断是否插过了。当时出了这个bug我懵逼了,什么鬼!!后来上网查了一下以及问了主管,这个这个程序端是不好控制并发的(我目前的理解也是这样的),我目前能想到并且理解的也就只有这个了。好了BBBB说了一大堆。现在开始说解决方法。  在数据库层面上乐观锁对于update那个是很简单的,无非在设计表的时候新增一个字段,如:version 这个字段用来记录更新的次数,只加不减,就是用来防止程序多次更新某条数据,然后出现问题。  举个例子吧,对自己的理解也有帮助。 比如某一张表 有id,name,status,version  一共四个字段,假设这是订单表,其中订单表有 未发货、已发货、已签收、拒发货这四个状态。有2个管理员,同时操作某个用户,一个是操作为已发货,一个是操作未拒发货。这时候程序是不管的,就按照先后顺序直接执行一遍。这时双方都是互相不知道对方做了什么操作,都以为自己操作成功了。但是肯定是有一个管理员得到结果不是自己想要的,那么这个时候是不是应该出现提示,说订单状态已经被改变了,然后最后操作的那个管理员需要确认后才能进行操作。那么如何避免呢?这时候就需要用上version了。 假设初始化的时候version是1。在做了一次update操作后version的次数就变成2了。那么version也是要成为where的条件之一。

  1. update table set status='已发货',version = version+1 where version=1  

当时2个管理员看到的肯定是version为1的数据,那么他们同时操作,update安装这个写的话就只有第一个管理员会操作成功了。因为第二次操作的时候version已经变成2了。当然这只是一个很小的例子。实际情况实际考虑,解决方法应该是和这个类似的。


可是我今天遇到是insert,这时候就懵逼了,怎么解决呢?由于我们这个业务的特殊性,一个用户一条最多只能摇一次,那么也就是说insert每天最多执行一次。

我们正好有个数据的createDate,那么可以利用起这个字段,条件是今日是否已经插入了一条

  1. insert into `table` (createDate,字段2,字段3,字段4,user_id)  
  2. select now(),值2,值3,值4,#{user_id}  
  3. from dual where not exists(  
  4. select * from `table` where DATE(createDate) = DATE(now()) and   
  5. user_id = #{user_id}  
  6. )  
这样就可以避免同一用户,一天能够插入2条数据的尴尬情况。个人认为这个是很好的利用了数据库的原子性(不知道这样说会不会有问题)。sql执行语句的时候是严格按照先后顺序来的,只有前一条执行完成了,然后这个时候才执行下一条。正是利用了关系型数据的这个特点,才能在数据库层面解决一些并发问题。对数据的改动基本就是insert和update,只不过insert在插入的时候顺便查了一遍是否已经存在类似的数据罢了。这样就完美解决了这个bug。也不知道有没有其他的解决方法。

引用zyyr365的一段笔记吧:

使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
程序员容易忽略的SQL Server错误集锦 – 码农网
sql语句大全(详细)
SQL向数据库中添加一条新数据 | VBA实例教程
Excel与Access的数据交互——sql增、删、改基础语句
MySQL数据导入导出
数据库基础
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服