避免几个人编辑同一段数据所造成的冲突 悲观锁和乐观锁的区别

本文探讨了在Web应用中,如何避免多人编辑同一数据时产生的冲突,介绍了悲观锁和乐观锁两种策略,分析了它们的优缺点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在web应用中,怎么样避免几个人编辑同一段数据所造成的冲突?
多人编辑同一条数据的情况有很多一般有两个办法:
1.编辑前加锁(悲观锁);
在当前用户编辑数据初始化之前,判断当前数据是否已经被别人锁定。如果已经锁定,那么提醒用户,当前数据正在被其他人编辑,并且让页面显示只读;如果没有锁定,那么系统锁定当前数据。要实现这样的功能可以在数据库里添加两个字段:是否被锁定,锁定用户。
这样的好处是能让当前用户知道已经被别人锁定,避免在编辑之后才提醒,做无用功。
缺点是数据解锁比较麻烦,就是用户退出编辑的方法有很多种,比如直接关闭页面,这样就锁定了数据而没有释放。这样可以做一个解锁的页面让管理员使用,或者在系统关闭的时候执行批处理来解锁。
这个方法用在同一条数据被多人同时编辑的可能性较大的时候。
2.编辑后加提醒(乐观锁);
页面允许多个人同时编辑,谁先提交谁生效。可以在数据库里设置一个字段叫做LastModifyTime(时间戳类型),编辑之前获得这个时间,提交的时候比较这个时间,如果相等则允许更新,不相等则提示用户已经被别人编辑过,请重新加载数据。
好处:实现简单
坏处:会让用户做无用功
适用于多人同时编辑可能性较小的情况。

悲观锁和乐观锁的区别:
乐观锁:先进行业务操作,不到万不得已不去拿锁。每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁或CAS操作。
version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,在读取数据的同时也会读取version值,在提交更新时,若读取到的version值为当前数据库中的version值相等时更新,否则重新更新操作,直到更新成功。SQL代码: update table set x=x+1,version=version+1;
CAS操作:即compare and swap 或者compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当数据更新时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。
悲观锁:先获取锁,再进行业务操作。每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
总结
1.乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能;
2.乐观锁还适用于一些比较特殊的场景,例如在业务操作过程中无法和数据库保持连接等悲观锁无法适用的地方;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值