乐观锁+版本号

本文介绍了在并发环境下,Java结合MySQL如何利用乐观锁和版本号实现数据一致性。通过示例展示了线程A和线程B在更新同一记录时,线程A成功更新并增加版本号,而线程B因版本不匹配导致更新失败的过程。解释了悲观锁、乐观锁的概念,并给出了MyBatisPlusConfig配置和数据操作的代码示例。
摘要由CSDN通过智能技术生成

场景

两个线程,比如线程A,线程B,同时取id=1得记录。这个时候两个线程获取的版本号都是1。

接下来,线程A修改了name和version自增,提交事务。这个时候update的语句应该如下:

update 表 set name=’开发’ ,version=version+1 where id=1 and version =1  ,执行成功 后数据库表的id=1这条记录versoin=2了。

在接下来,由于线程B动作比较慢,等线程A已经提交了,然后执行Update

update 表 set name=’全栈’ ,version=version+1 where id=1 and version =1, 发现执行不了了。失败。

 

名词解释

1.悲观锁

当要对数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制,在修改数据之前先锁定,再修改的方式被称之为悲观并发控制【又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”】。

2.乐观锁

乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候ÿ

乐观锁是一种并发控制机制,它的主要思想是在数据更新时,利用版本号或时间戳等方式记录数据的历史版本,防止多个事务同时对同一数据进行修改而导致数据不一致的问题。 在基于版本号乐观锁实现中,每个数据记录都会有一个版本号,每次更新数据时都会将版本号加1。在更新数据时,先检查当前数据的版本号是否与要更新的版本号相同,如果相同则表示该数据没有被其他事务修改过,可以更新数据并将版本号加1;如果不同,则表示该数据已经被其他事务修改过,当前事务需要回滚或者重新尝试更新数据。 下面是一个简单的示例代码: ```java // 假设有一个 user 表,其中 version 字段为版本号 public void updateUser(User user) { int version = user.getVersion(); // 获取当前版本号 user.setVersion(version + 1); // 更新版本号 // 执行更新语句,带上版本号作为条件 String sql = "UPDATE user SET name=?, age=?, version=? WHERE id=? AND version=?"; int rows = jdbcTemplate.update(sql, user.getName(), user.getAge(), user.getVersion(), user.getId(), version); if (rows == 0) { // 更新失败,抛出异常或者进行回滚等操作 } } ``` 在上面的代码中,我们通过获取当前版本号并将其加1来更新数据的版本号,然后在执行更新语句时,将版本号作为条件进行限制。如果更新成功,则表示该数据没有被其他事务修改过,更新完成;如果更新失败,则表示该数据已经被其他事务修改过,当前事务需要进行回滚或者重新尝试更新数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值