当前位置:首页 > 日记 > 正文

MySQL中选择+更新处理并发更新问题解决方案共享

MySQL中选择+更新处理并发更新问题解决方案共享
问题的背景:

假设MySQL数据库有一个成员表vip_member(InnoDB表),和结构如下:

当会员欲继续购买会员(只需1个月、3个月或6个月)时,必须符合以下条件:

如果end_at比现在的时间早,为当前时间设置为当前时间加上start_at,购买月数end_at。

如果end_at等于或晚于当前时间,通过end_at = end_at +买的月数集

继续购买后,active_status必须是1(即激活)

问题分析:

针对以上情况,我们通常检查记录的第一选择,然后记录end_at和更新start_at和end_at据记载。伪代码如下(UID为1001的会员1个月)。

复制代码代码如下所示:
vipmember =选择*从vip_member uid = 1001,极限1 uid 1001 #检查成员
如果vipmember.end_at <现在():
更新vip_member集start_at =现在(),end_at = date_add(现在的(),间隔1个月),active_status = 1,updated_at =现在()在uid = 1001
其他的:
更新vip_member集end_at = date_add(end_at,间隔1个月),active_status = 1,updated_at =现在()在uid = 1001
如果有两个线程同时执行上面的代码,那么很明显,存在一个数据覆盖问题,即一个要持续1个月,一个要持续2个月,但它可能只持续2个月,而不是增加到3个月。

解uff1a

首先,我想把选择和更新与SQL结合起来,如下所示:

复制代码代码如下所示:
更新vip_member

start_at =案例
当end_at <现在()
然后现在()
其他start_at
结束,
end_at =案例
当end_at <现在()
然后date_add(现在的(),区间#时间:整数#月)
其他date_add(end_at,间隔时间:#整数#月)
结束,
active_status = 1,
updated_at =现在()
在UID = # UID:bigint #
限制1;
很容易!

B,第二种方案:事务,即用事务包装上面的选择+更新操作。

那么包装上的交易是否一切都会没事的。

显然不是。因为如果两笔交易都选择同一vip_member记录在同一时间,然后同样会发生数据覆盖的问题。所以,我们能做什么来解决它你想设置事务隔离级别为可序列化的,考虑到现实的表现。

我们知道,InnoDB支持行锁。看MySQL官方文档(InnoDB锁定读)理解InnoDB可以添加两个锁时,读取行数据:读写互斥锁和共享锁。

读共享锁是通过以下SQL获得的:

复制代码代码如下所示:
选择*从父母那里的名字= 'jones'lock共享模式;
如果事务A获得第一读和共享锁,事务b仍然可以读取带有共享共享锁的行数据,但在等待事务提交或回滚之后,它可以使用读共享锁更新或删除行数据。

复制代码代码如下所示:
选择counter_field从child_codes更新;
更新child_codes集counter_field = counter_field + 1;
如果事务A首先获得一行的写共享锁,则事务b必须等待事务提交或回滚访问行数据。

很显然,要解决会员身份更新问题,不能添加读取共享锁,只能添加一个共享锁,前面的SQL重写如下:

复制代码代码如下所示:
vipmember =选择*从vip_member哪里UID = 1001限1更新1001 # UID检查成员
如果vipmember.end_at <现在():
更新vip_member集start_at =现在(),end_at = date_add(现在的(),间隔1个月),active_status = 1,updated_at =现在()在uid = 1001
其他的:
更新vip_member集end_at = date_add(end_at,间隔1个月),active_status = 1,updated_at =现在()在uid = 1001
此外,我想提醒您,更新/删除SQL应该尽可能地在条件下设置索引过滤条件,否则将锁定表,性能可以想象它有多糟糕。

c、第三种方案:乐观锁、类CAS机制

第二种锁定方案是悲观锁机制,并选择…对于更新不是很常见,它与CAS实现的乐观锁定机制相关联,所以我想到了第三种解决方案:乐观锁。

具体来说,它是相当简单的,首先,选择SQL不做任何修改,然后将选择出的vip_memer在更新SQL WHERE条件的end_at条件如下:

复制代码代码如下所示:
vipmember =选择*从vip_member uid = 1001,极限1 uid 1001 #检查成员
cur_end_at = vipmember.end_at
如果vipmember.end_at <现在():
更新vip_member集start_at =现在(),end_at = date_add(现在的(),间隔1个月),active_status = 1,updated_at =现在()的地方,active_status = 1。
其他的:
更新vip_member集end_at = date_add(end_at,间隔1个月),active_status = 1,updated_at =现在()在uid = 1001
这样,我们就可以根据更新的返回值来判断更新是否成功。如果返回值为0,则表示有并发更新。那么我们只需要重试它。

方案的比较:

对这三种方案的优缺点,可能有不同的意见,只是说我自己的意见。

第一种方案使用复杂的SQL来解决问题,不利于维护,因为SQL中的具体业务组合,在修改业务之后不仅需要读取此SQL,也可能会更改为更复杂的SQL。

第二种方案写一个独占锁,可以解决这个问题,但不常用。

第三个解决方案应该是一个平庸的解决方案,即使没有交易,我个人也推荐它。
此外,乐观锁和悲观锁的选择一般都是这样的(参照第二篇文章的结尾):

如果对阅读的响应非常高,比如证券交易系统,则使用乐观锁是合适的,因为悲观锁会阻塞读。

如果读得远多于写,它也适合使用乐观锁,因为悲观锁会导致少量的写阻塞大量的阅读。

如果写频繁,冲突的比例很高,则适合悲观的写锁。

相关文章

monitr32.exe的功能是什么该monitr

monitr32.exe的功能是什么该monitr

查询,功能,过程,电脑软件,exe,点评:monitr32.exe是canonmulti通过打印机相关程序 进程文件:monitr32或monitr32.exe 进程名称:佳能monitr32 过程类别:安全风险的过程 英文描述: monitr32.exe安装与TH canonmulti司机通过prniter系列。这一系列…

oracle数据库基本通用命令摘要

oracle数据库基本通用命令摘要

命令,数据库,通用,摘要,电脑软件,1。获取数据库名称和创建日期。 选择名称,创建,log_mode,open_mode V $数据库; 2、oracle数据库中的计算机主机名、oracle数据库实例名称和oracle数据库管理系统版本信息 选择host_name,instance_name版本,从V $…

conime.exe进程是怎样的

conime.exe进程是怎样的

进程,是怎样,电脑软件,conime,exe,点评:conime.exe是输入法编辑器相关程序。注意:conime.exe可能bfghost1.0远程控制的后门程序在同一时间。这个程序允许攻击者访问你的计算机,窃取密码和个人数据。它表明,这一过程被立即删除。 请耐心等待,知道…

winrecon是winrecon.exe-过程

winrecon是winrecon.exe-过程

过程,电脑软件,winrecon,exe,评论:winrecon.exe - winrecon过程 进程文件:winrecon或winrecon.exe 进程名称:NoLoad WinRecon 过程类别:安全风险的过程 英文描述: winrecon.exe由空载提供侦察/监视工具,记录发生的一切在你的计算机中的应用。该…

是directx.exe病毒程序DirectX进程

是directx.exe病毒程序DirectX进程

进程,程序,电脑软件,directx,exe,点评:directx.exe的blaxe或logpole部分病毒 进程文件:DirectX或directx.exe 过程名称:DirectX 过程类别:安全风险的过程 英文描述: directx.exe已被证实是blaxe和logpole病毒。这个文件 中文参考: directx.exe…

开启或关闭Bing在Win8.1系统在线搜

开启或关闭Bing在Win8.1系统在线搜

搜索,系统,在线,方法,电脑软件,点评:在Windows 8.1中,超级按钮的搜索功能可以显示在线搜索。在这里,我们介绍如何打开或关闭Bing在Win8.1系统在线搜索,感兴趣的朋友可以参考一下。 在Windows 8中,只能搜索本地文件,但在Windows 8.1中,超级按钮的搜…

怎么查自己的手机号是多少,怎么显

怎么查自己的手机号是多少,怎么显

怎么查自己的手机号是多少,怎么显示自己手机号码,用户,方法,显示,选项,打电话,选择,简单,安卓,很多情况下,我们新买的手机卡使用时,当别人问起电话号码时自己也记不清,那么怎么查自己的手机号码呢?最简单的方法是如果朋友在旁边,直接打电话给他就可以看…

解决错误的表mysql.plugin不存在的

解决错误的表mysql.plugin不存在的

错误,不存在,电脑软件,plugin,mysql,一般的原因是,到my.ini数据库文件存储地址由手动变化引起的手动更改 当MySQL服务启动时,找不到内置的数据库MySQL,也找不到表,上面的错误被包装起来了。 解决方案:将安装目录中的MySQL数据库或以前的目录复…

该spbbcsvc.exe-角色spbbcsvc过程

该spbbcsvc.exe-角色spbbcsvc过程

角色,过程,电脑软件,spbbcsvc,exe,点评:SPBBCSvc.exe是赛门铁克网络安全套件的一部分来保护您的计算机的安全性 进程文件:spbbcsvc或spbbcsvc.exe 过程名称:赛门铁克互联网安全服务 过程类别:安全风险的过程 英文描述: spbbcsvc.exe是赛门铁克…

mysql数据库设计复习笔记与项目实

mysql数据库设计复习笔记与项目实

项目实战,数据库设计,笔记,电脑软件,mysql,作者:杨欣琦 最近有3个项目开工,其他2个是从底层开始,开始了一段时间,在小团队开发条件的小城市,没有DBA做数据库的设计和维护,开发商往往在上面,但看到许多数据库的设计,我觉得很多设计是不完美的,包括DZ…

息屏提醒开启一直显示功能的具体方

息屏提醒开启一直显示功能的具体方

息屏提醒开启一直显示功能的具体方法,息屏提醒,开启一直显示,大家知道息屏提醒怎么设置一直开启吗?今天小编教大家息屏提醒开启一直显示功能的具体方法,我想一定会对你有所帮助的。息屏提醒开启一直显示功能的具体方法1、大家想要设置息屏提醒…

MySQL数据表损坏原因分析及修复方

MySQL数据表损坏原因分析及修复方

方法,推荐,损坏,数据表,原因,1者损害原因分析。米 以下原因是MySQL表被破坏的常见原因: 1。服务器突然断电导致数据文件被损坏。 2。强制关机,不关闭MySQL服务。 3、在mysqld进程时被桌子上写。 4。而用myisamchk,mysqld也操作表。 5,磁盘故障…