回忆一下数据库中的锁问题

在我们日常的工作中,有些业务是需要严格控制顺序和次数的,比如我今天要说的关于微信上面体现的逻辑。

业务场景:

微信用户发起提现请求,用户输入提现金额,请求接口!然后我们就会生成一条提现的请求,一个定时任务扫描这张表,进行企业大款的操作。

那么问题在哪里呢?假设用户连续两次发起请求,提现6元,请求几乎同步的情况下。代码中两次验证可提现金额都通过了(因为取出来都是10,都大于6),这个时候去操作表,减少这个可提现金额,就可能减到负数,然后生产了两条提现的记录到表中,定时任务一扫,就进行了两次打款,血亏!所以需要避免这种情况!

解决方式是什么呢!像这种情况下,一般的思路是用乐观锁的方式去解决(乐观锁只是一种概念,没有具体的锁),当然也可以用悲观锁,for update暴力锁住这条记录,然后修改,提交。但是这样一来就效率比较低下。

那么乐观锁,顾名思义就是比较乐观了,相信一般情况下是不会发生这种情况的,所以直到提交更新的时候才去检测是不是有数据的冲突,如果有冲突就直接告诉用户有问题就完事了

那么具体是什么意思呢?就微信提现这个业务逻辑来说 update user set have_money = (have_money - 6) where (have_money - 6) > 0 and id=2;

这样如果这条语句执行失败,说明可提现余额不足了,也不需要新增一个提现请求记录了。这种方式是条件限制式的乐观锁,另外一种方式是版本号的形式,这种形式大家可以自行百度。

原文地址:https://www.cnblogs.com/changeCode/p/11272745.html

时间: 2024-10-24 12:40:01

回忆一下数据库中的锁问题的相关文章

数据库的隔离级别对应的就就是数据库中的锁

------------------------------------------------------ 数据库中的几种隔离级别 read uncommited--读未提交 该隔离级别指即使一个事务的更新语句没有提交,但是别的事务可以读到这个改变,几种异常情况都可能出现.极易出错,没有安全性可言,基本不会使用. read committed --读已提交 该隔离级别指一个事务只能看到其他事务的已经提交的更新,看不到未提交的更新,消除了脏读和第一类丢失更新,这是大多数数据库的默认隔离级别,如O

关系型数据库(五),数据库中的锁

目录 1.锁的分类 2.共享锁和排斥锁 3.乐观锁与悲观锁 五.数据库中的锁 1.锁的分类 2.共享锁和排斥锁 共享锁(读锁) 排斥锁(写锁) 3.乐观锁与悲观锁 (1)悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程).传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.Java中sy

数据库中乐观锁与悲观锁的概念

锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性.如在金融系统的日终结算 处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行过程中 (可能是几秒种,也可能是几个小时),数据再发生变化.此时,我们就需要通过一些机 制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓 的 " 锁 " ,即给我们选定的目标数据上锁,使其无法被其他程序修改. Hibernate 支持两种锁机制:即通常所说的 " 悲

数据库中的锁

1 前言 数据库大并发操作要考虑死锁和锁的性能问题.看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一个线程,T2 为另一个线程.T3,T4以此类推.下面以SQL Server(2005)为例. 2 锁的种类 共享锁(Shared lock). 例1: ---------------------------------------- T1: select * from table (请想象它需要执行

Spring中的事务与数据库中的锁关系

本文只先简单的介绍下Spring中的事务与DB中锁的关系. 首先总结:Spring事务的实现本质上是使用的DB中的事务,而DB中的事务实现又主要依靠DB中的锁.所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁. 所以大家一定要厘清DB事务与DB各种锁的原理与概念.后续我也研究一下DB锁,并结合具体的生产环境监控数据来谈谈. <以下是转载部分内容.主要是Spring事务的使用方式.隔离级别之类的> 那么事务的隔离级别与锁有什么关系呢?本人认为事务的隔离级别是通过锁的

DB2查看数据库中的锁信息

利用"db2 connect to <db name>"连接到数据库后,执行相关指令 查询锁快照信息 db2 get snapshot for locks on <db name> 查询目前存在的锁 db2 SELECT AGENT_ID, LOCK_OBJECT_TYPE, LOCK_MODE, LOCK_STATUS FROM SYSIBMADM.SNAPLOCK 某一个用户的锁的情况 get snapshot for locks for applicati

事务和锁--查看数据库中的锁

数据库加锁是修改哪一条加锁,还是在页上加锁,还是在表上加锁,数据库来决定 如果你更改的是两条记录,就在两条记录上加锁,如果你更改的是很多条,这个时候数据库一看一条一条加锁太麻烦,给整个页加锁更省事,或者给整个表加锁更加省事 加锁的级别越大,数据库越省事,数据库越省事,并发性越差,修改一条记录如果给表加上独占锁,那么想查询别的记录都查询不了了 加锁的对象越小,并发性越好 加的锁对象越大,并发性越差 刚开始就这几个锁 1.开启事务修改学生的名字,给学号为0000000001的学生姓名加个‘_01’,

数据库中的共享锁和排他锁

共享锁,又称为读锁,获得共享锁之后,可以查看但无法修改和删除数据. 排他锁,又称为写锁.独占锁,获得排他锁之后,既能读数据,又能修改数据. 为什么要加锁 很多人都知道,锁是用来解决并发问题的,那么什么是并发问题呢?并发情况下,不加锁会有什么问题呢? 拿生活中的洗手间举例子,每个洗手间都会有一个门,并且是可以上锁的,当我们进入洗手间之后会把门反锁,当我们出来之后再把锁打开. 当门被锁上之后,其他人只能在门外等待.洗手间之所以要有门锁,就是为了保护隐私的,避免出现多个人同时进入洗手间的情况. 这和数

MySQL:聊一聊数据库中的那些锁

在软件开发中,程序在高并发的情况下,为了保证一致性或者说安全性,我们通常都会通过加锁的方式来解决,在 MySQL 数据库中同样有这样的问题,一方面为了最大程度的利用数据库的并发访问,另一方面又需要保证每个用户能以一致的方式读取和修改数据,就引入了锁机制. 在 MySQL 数据库中,锁有很多种类型,不过大致可以分为三类:全局锁.表级锁.行级锁.这篇文章我们就简单的聊一聊这三种锁. 全局锁 全局锁是粒度最大的锁,基本上也使用不上,就像我们家的大门一样,控制这整个数据库实例.全局锁就是对整个数据库实例