java多用户同时修改一条数据时乐观锁怎么用的?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多用户同时修改一条数据时乐观锁怎么用的?相关的知识,希望对你有一定的参考价值。
乐观锁要加version字段控制,但我看了公司项目代码(单机传统项目),好像都没有加版本控制呢?难道不需要考虑以上问题,而且我接触的一些项目好像很少给数据库表进行 乐观锁的版本控制呢?这是怎么回事
你说的这个version是mysql底层的锁机制提供的,并不是java提供的。使用数据版本(Version)记录机制实现,这是mysql乐观锁最常用的一种实现方式。所谓的数据版本就是给数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加1。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,版本号重新读取再做更新。追问
version是mysql底层的锁机制提供的??这个怎么佐证?
参考技术A 具体业务具体分析吧。如果我每个增删改查都需要加版本控制,那多费事啊。现在互联网讲究快速迭代式开发。一个初版,尽快上线,然后频繁的迭代。
但是有些业务就需要做安全控制了。这里可以先把业务拆分为核心业务和非核心业务。对核心业务再看其是否需要具体的安全措施。比如转账,充值等操作。这就是一定需要做安全控制的。
这里的安全控制包含很多,线程安全,数据安全,权限安全...追问
你意思对一般的普通的表的增删改就不用考虑多个用户同时修改1条数据了吗??业务重要的才考虑?
追答是的。update where本身自带了行级锁。如果不是并发调用同一个update where 条件的话,是没有任何问题的。
行级锁就是,2个update where同一个条件的时候,会锁住where条件数据,就变成了一次修改,这也是乐观锁的sql层面保证依据。
一般update并发是很少的。如果多的话就是上面我说的核心业务了,转账,扣库存等等。普通的业务操作,在用户容忍范围内,就不需要考虑了。具体业务具体分析嘛。
看样子你不是很理解乐观锁,我这里简单给你说一下,乐观锁就是认为所有update都不会出问题。但是如果出问题了就麻烦了。所以这里使用了version进行版本控制。然后有mysql的InnoDB引擎提供的行级锁来保证其能够实现同一时间同一条件只会有一个update在执行。
假设一个场景,扣库存,现在1000个库存,100个并发过来,先获取版本号,然后根据版本号扣库存,100个并发过来全都是version=1 and product_id=1,那么100个请求有且只会有一个人扣除库存,然后其他都失败。一般可以采用轮询机制。重复select version ->update version+1 。
比如对一个产品表进行增删改,一个锁没有啊,不管是悲观锁还是乐观锁
多用户同时操作一条Mysql记录问题
场景:两个用户同时读取了数据库中的一条记录,此时用户A对其中一个字段的值进行了修改操作并进行了提交,后来用户B也对这个字段进行了修改,用户B的提交将会覆盖用户A提交的值
关于乐观锁和悲观锁
悲观锁:每次去取数据,很悲观,都觉得会被别人修改,所以在拿数据的时候都会上锁。
简言之,共享资源每次都只给一个线程使用,其他线程阻塞,等第一个线程用完后再把资源转让给其他线程。
synchronized和ReentranLock等都是悲观锁思想的体现。
乐观锁:每次去取数据,都很乐观,觉得不会被被人修改。
因此每次都不上锁,但是在更新的时候,就会看别人有没有在这期间去更新这个数据,如果有更新就重新获取,再进行判断,一直循环,直到拿到没有被修改过的数据。
CAS(Compare and Swap 比较并交换)就是乐观锁的一种实现方式。
参考
Mysql 事务及数据的一致性处理
https://segmentfault.com/a/1190000012469586
CAS乐观锁解决并发问题的一次实践
https://www.javazhiyin.com/41189.html
以上是关于java多用户同时修改一条数据时乐观锁怎么用的?的主要内容,如果未能解决你的问题,请参考以下文章