qq_35639418 2017-05-17 02:57 采纳率: 100%
浏览 2411
已采纳

mysql 锁的问题,订单防重复

需求是这样,订单表,防止重复订单,如已存在状态为成功的订单则不允许插入,如已存在状态为失败的订单则允许插入。

正常来说,插入之前先查询一下有没有已成功的订单并上锁就好,但是MYSQL 行锁锁不住不存在的数据。

比如事务1,查询了发现不存在,就去插入,
事务2在事务1插入前也查询了,也发现不存在,也去插入

MYSQL 有没有意向锁之类的机制呢,比如说我准备要插入ID为1的数据了,你们都别插入。

  • 写回答

3条回答 默认 最新

  • Himly_Zhang 2017-05-17 03:23
    关注

    感觉你解决问题的出发点就是错的。所谓订单重复问题,就是同一笔订单多次提交的问题。可能造成的原因。比如在网页上极快的速度点击两下提交。或者网络
    情况不好。第一次提交还没有返回结果,第二次又进行提交。或者,比如一个账号同时在多个浏览器登录,两个浏览器同时提交一个一样的订单。

    首先从请求发出的地方。应该严格限制点击,点击后必须有结果返回才能进行第二次点击。如果命令已经发出去了。不允许第二次点击。或者用简单的按钮
    遮罩或者倒数或者隐藏的方式,来控制多次点击。
    然后从请求处理的地方。订单提交应该尽量控制是单线程访问。当然如果并发极高的情况下。单线程就不适用了。那么我们是不是要在内存里面暂时的
    记录一下订单状态。根据订单状态返回给客户信息。
    最后才是从数据库方面。数据库方面其实很简单。就是一个乐观锁或者悲观锁的问题。但是这个锁看你怎么设计。
    比如订单的设计应该是先创建再提交。创建的时候订单已经插入了。但是只有提交了才生效。悲观锁来说。当有不同的人请求这个订单信息的时候。
    第一个就for update,锁死。其他人不让动。
    乐观锁呢。就是。第一个人拿到这个信息的时候。更新这个数据的一个版本号字段。当我往回更新的时候。应该先判断这个数据的版本号是不是我拿走
    的时候的版本号,如果是。可以更新。如果比这个版本号大。说明别人已经把这个数据拿走了。他也可能更新。那我的这次更新视为无效。提醒用户
    重新获取。

    最后总结。锁的机制都是自己根据业务设定的。不要祈求数据库能帮你干啥。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)
  • ¥15 关于并联谐振电磁感应加热
  • ¥15 this signal is connected to multiple drivers怎么解决
  • ¥60 请查询全国几个煤炭大省近十年的煤炭铁路及公路的货物周转量
  • ¥15 请帮我看看我这道c语言题到底漏了哪种情况吧!
  • ¥66 如何制作支付宝扫码跳转到发红包界面
  • ¥15 pnpm 下载element-plus