首页 > 数据库 >mysql:使用乐观锁保护数据一致性和完整性

mysql:使用乐观锁保护数据一致性和完整性

时间:2024-08-05 18:21:19浏览次数:10  
标签:加锁 乐观 并发 完整性 冲突 mysql 一致性 数据 result

在数据库操作中,保持数据一致性和完整性至关重要。乐观锁(Optimistic Lock)是一种不锁定资源的锁机制,它在数据更新时才会检测是否发生冲突。本文将介绍乐观锁的概念、使用方法、优缺点,并特别罗列它与悲观锁的区别。

乐观锁的概念

乐观锁基于这样一个假设:数据冲突并不频繁发生,因此在读取数据时不对其加锁,而在更新数据时检测是否发生冲突。乐观锁通常通过在记录中增加一个版本号(或时间戳)字段来实现,在更新时检查版本号是否一致。如果版本号不一致,则表示数据已经被其他事务修改,此时更新操作会失败。

乐观锁是业务实现的,不加锁。

乐观锁的使用示例

以下示例展示了如何在使用GORM(一个流行的Go语言ORM框架)时应用乐观锁:

// 乐观锁
result := tx.Model(&NifishuntGame.TgUser{}).Where("status=?", "pending").
    Update("status", "success"))
if result.Error != nil {
    log.Println("Update Status Error:", result.Error)
    return result.Error
}

if result.RowsAffected == 0 {
    return errors.New("status_is_not_update")
}

在这个示例中:

我们在更新status字段时检查status字段是否匹配,如果不匹配则表示数据已经被修改,从而避免了并发冲突。

如果result.RowsAffected!=0,表示获得了这个锁,可以进一步完善其他逻辑功能(比如完成发放奖金等等)

如果result.RowsAffected==0,表示这个状态已经被其他协程处理了,这里默认就可以不处理了(因为已经有人在处理了)。

想下另外一个需求: 假设数据库有个字段i=1, A/B两用户都想给i+1,采用乐观锁会遇到什么问题?

  1. 可能有一个人成功,另外一个人不成功,这时候不成功的人需要重试,以解决冲突问题

  2.需要采用最终一致性

乐观锁的优点

  1. 高并发性能:乐观锁不在读取数据时加锁,因此对并发性能影响较小,适用于高并发环境。
  2. 实现简单:不需要维护复杂的锁机制,只需在更新时进行冲突检测即可。
  3. 减少死锁风险:由于乐观锁不加锁,因此不会产生死锁问题。

乐观锁的缺点

  1. 冲突处理复杂:在更新时如果检测到冲突,需要处理冲突并重试更新操作,这增加了应用程序的复杂性。
  2. 适用场景有限:乐观锁适用于数据冲突较少的场景,如果数据冲突频繁发生,乐观锁的重试机制可能会导致性能下降。

乐观锁与悲观锁的区别

  1. 锁定时机

    • 乐观锁:在读取数据时不加锁,仅在更新数据时检测冲突。
    • 悲观锁:在读取数据时即加锁,确保其他事务无法同时修改该数据。
  2. 性能影响

    • 乐观锁:对并发性能影响较小,适用于高并发环境。
    • 悲观锁:对并发性能影响较大,适用于数据一致性要求高的环境。
  3. 死锁风险

    • 乐观锁:由于不加锁,不会产生死锁问题。
    • 悲观锁:可能产生死锁,需要小心设计和处理。
  4. 实现复杂度

    • 乐观锁:实现相对简单,但需要处理冲突和重试逻辑。
    • 悲观锁:实现较复杂,需要维护锁的状态和顺序。

适用场景

乐观锁适用于以下场景:

  1. 高并发环境:如社交网络、在线游戏等用户并发操作频繁的场景。
  2. 数据冲突较少:适用于数据更新冲突较少的场景,如用户个人信息更新等。

乐观锁适合用在不容易出现冲突的情况,比如用户的个人数据上面;如果是全局的数据必须采用悲观锁

结论

乐观锁是一种高效的并发控制机制,适用于高并发、低冲突的场景。相比悲观锁,乐观锁对系统性能的影响较小,但需要处理数据冲突的情况。在实际应用中,应根据具体场景和需求选择合适的锁机制,以实现最佳的性能和数据一致性。

希望本文对你理解和使用乐观锁有所帮助。如果你有任何问题或建议,欢迎留言讨论。

标签:加锁,乐观,并发,完整性,冲突,mysql,一致性,数据,result
From: https://www.cnblogs.com/zhanchenjin/p/18343770

相关文章

  • mysql 行级锁(按照粒度分类)
    MySQL支持多种锁机制,以确保数据的一致性和完整性。其中,行级锁(Row-LevelLocking)是一种细粒度的锁机制,能够锁定单行数据,从而允许高并发访问。本文将简要介绍MySQL行级锁的概念、使用场景及其优缺点。行级锁的概念行级锁是一种细粒度的锁机制,允许事务在操作数据时仅锁定特定的行,而......
  • mysql:使用悲观锁保护数据完整性
    在数据库操作中,确保数据一致性和完整性至关重要。悲观锁(PessimisticLock)是一种锁机制,它在读取数据时就对其加锁,从而防止其他事务同时修改该数据。本文将介绍悲观锁的概念、使用方法,以及它的优点和缺点。悲观锁的概念悲观锁是一种认为并发操作总会发生冲突的锁机制。当一个事务......
  • 003.flask与Mysql的连接以及增删改查
    目录Flask与Mysql的连接以及在Flask中对数据库进行增删改查1.创建文件并且配置2.flask与Mysql数据库进行连接以及检测是否连接成功3.创建一个类对象User以及将属性添加到数据库中4.在flask中进行数据库的增删改查5.总结Flask与Mysql的连接以及在Flask中对数据库进行增删改查p......
  • Mysql的length函数,char_length函数与字符,字节的区别
    在存储中,1个英文单词或1个英文字符为1个1字节,1个中文或1个中文字符为3个字节 在Mysql5.0之前,VARCHAR(20)中的20表示20个字节,英文可以存储20个,但中文只能存储6个 在Mysql5.0之后,varchar(20)中的20表示20个字符,不管中文还是英文都可以存储20个 length()函数是查找字节数,CHAR_LENG......
  • 003.flask与Mysql的连接以及增删改查
    Flask与Mysql的连接以及在Flask中对数据库进行增删改查python解释器:3.8.3版本flask==2.2.2版本flask_sqlalchemy=3.1.1flask_migrate==4.0.71.创建文件并且配置创建一个大文件在该文件中进行创建static(静态),templates(动态文件),app.py文件将大文件移到vsc......
  • mysql8安装和部署
    mysql8.0详细安装教程参考文章 一、拉取mysql8.0数据库镜像dockerpullmysql:8.0二、创建配置、数据、日志挂载目录mkdir-p/data/mysql/confmkdir-p/data/mysql/datamkdir-p/data/mysql/logs三、新建my.cnf配置文件1、进入配置文件夹cd/data/mysql/conf2......
  • mysql分区自动维护(SpringBoot+MybatisPlus)
    1.环境SpringBoot+MybatisPlus+MySQL2.简介通过定时器@Scheduled每日触发,查询当前库中所有分区表(这里以时间段进行分区)判断剩余分区是否小于自定义预留分区(无自定义预留分区则取默认分区配置),若小于预留分区时,自动创建分区至配置分区数判断已有分区是否大于自定义保留分......
  • springboot多数据源整合及使用(一个oracle,两个mysql)
    在开发工作中,会遇到需要使用多个数据源的情况,比如项目一开始只有oracle,后面需要追加两个mysql数据源使用,这时候就需要配置多数据源了.首先,配置文件的编写:版本如下spring:datasource:db1:driver-class-name:com.mysql.cj.jdbc.Driverurl:......
  • 系统整容纪:用知识来"武装"自己~认识MySQL的锁与事务
    本文通过介绍在实际工作中一次异常排查引发的自我思考与学习,来使得读者受到一定的启发,从而迸发出星星点光,扩展出自己独有的思路,进而在工作中不断的挖掘自我不足之处,同时通过学习与"锻炼"来不断地强大自己。分享工作中的点点滴滴,贯彻千里之行,始于足下,最终以微不足道的量变引起化蝶......
  • 华为欧拉系统离线安装MySQL5.7步骤
    一、需要准备的软件1、mysql官网下载地址:https://dev.mysql.com/downloads/mysql/下载mysql-5.7.24-linux-glibc2.12-x86_64.tar二、下面开始部署安装mysql1、创建新的用户组和新的用户,用来管理mysql,提高安全性#创建新数组mysqlgroupaddmysql#创建用户mysql,指......