mysql乐观锁实现_mysql乐观锁实现

在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是著名的并发性问题。

典型的冲突有:

1.丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改为2,用户B把值从2改为6,则用户A丢失了他的更新。

2.脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改为2,用户A读到的值仍为6。

为了解决这些并发带来的问题。 我们需要引入并发控制机制。

二、 并发控制机制

锁,即给我们选定的目标数据上锁,使其无法被其他程序修改。

1.悲观锁:指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态

2.乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。乐观锁不能解决脏读的问题。

三、乐观锁的实现

a、使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据

b、使用自增长的整数表示数据版本号。更新时检查版本号是否一致,比如数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)作比较,如果相等,则可以更新,如果不等则有可能其他程序已更新该记录,所以返回错误。

1.数据库表设计

task

有三个字段,分别是id,value、version

2.实现

1)先读task表的数据(实际上这个表只有一条记录),得到version的值为versionValue

2)每次更新task表中的value字段时,为了防止发生冲突,需要这样操作

select (value,version) from task where id=#{id}

update task

set value=newValue,version=versionValue+ 1

whereid=#{id} and version=versionValue;

只有这条语句执行了,才表明本次更新value字段的值成功

如假设有两个节点A和B都要更新task表中的value字段值,差不多在同一时刻,A节点和B节点从task表中读到的version值为2,那么A节点和B节点在更新value字段值的时候,都操作 update task set value = newValue,version =  3   where version = 2;,实际上只有1个节点执行该SQL语句成功,假设A节点执行成功,那么此时task表的version字段的值是3,B节点再操作update task set value = newValue,version =  3   where version = 2;这条SQL语句是不执行的,这样就保证了更新task表时不发生冲突

转载于:

http://www.cnblogs.com/richerdyoung/p/6427668.html

MySQL中的乐观锁实现通常依赖于版本号或时间戳。其主要思路是,在数据更新时,先获取当前数据的版本号或时间戳,然后在更新数据时比较当前版本号或时间戳与更新前获取的版本号或时间戳是否相同,如果相同则执行更新操作,否则认为数据已经被其他事务更新,拒绝本次更新操作。 具体实现可以通过以下步骤来完成: 1. 在数据表中添加版本号或时间戳字段,用于记录数据的版本信息。 2. 在更新数据时,先查询出待更新数据的版本号或时间戳,并保存在变量中。 3. 执行更新操作前,再次查询数据的版本号或时间戳,并与之前保存的版本号或时间戳进行比较。 4. 如果两者相同,则执行更新操作;否则认为数据已经被其他事务更新,拒绝本次更新操作。 5. 在更新操作完成后,更新数据的版本号或时间戳。 具体实现可以使用MySQL的UPDATE语句,通过添加条件判断来实现乐观锁的效果。例如: ``` UPDATE table_name SET column1 = value1, ..., version = new_version WHERE id = target_id AND version = old_version; ``` 其中,`target_id`表示待更新数据的ID,`old_version`表示之前查询出的数据版本号或时间戳,`new_version`表示更新后的数据版本号或时间戳。如果`old_version`与`version`字段的值相同,说明数据没有被其他事务修改,可以执行更新操作;否则更新操作不会执行,可以通过返回值判断是否更新成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值