MybatisPlus的乐观锁实现

本文详细介绍了乐观锁的概念及其与悲观锁的区别,重点讲解了MybatisPlus如何实现乐观锁,包括在数据库中增加version字段、实体类中添加@Version注解以及配置乐观锁插件。通过成功和失败的测试案例,展示了乐观锁在并发更新时如何避免数据冲突,确保数据一致性。
摘要由CSDN通过智能技术生成

1、乐观锁的概念

乐观锁:由名字就可以知道,它十分乐观,认为每次的更新修改都不会被别人修改,所以不会上锁操作,出现问题,、
再次判断新值测试
悲观锁:名字就可以知道,它十分悲观,认为每次的更新修改都会被别人修改,所以每次操作都会上锁,再去操作

2、乐观锁实现方式

乐观锁实现的方式

  • 取出记录时,获取当前version
  • 更新时,带上这个version值
  • 执行更新时,把 set version = newversion where version = oldversion
  • 如果version不对,就更新失败

3、MybatisPlus实现乐观锁

1)在数据库表中增加字段version,并设置默认值version=1

2)在javaBean实体类中加上属性字段version

    @Version 
    private Integer version;

@Version:乐观锁Version注解

3)注册组件

//  扫描mapper文件
@MapperScan("sz.kingdom.testmybatisplus.mapper") 
@Configuration
public class MyConfiguration {
    
    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
    
}

4、测试

1)成功的测试案例

    @Test
    void TestOptimistSuccess() {
        tb_user user1 = userMapper.selectById(7);
        System.out.println("更新前:"+user1);
        user1.setName("ted1");
        int i = userMapper.updateById(user1);
        System.out.println("更新后:"+user1);
    }

输出日志:发现更新前后version值不一样
更新前:更新前:tb_user(userId=7, name=ted, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:46:31 CST 2021, version=6)
更新后:tb_user(userId=7, name=ted1, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:46:31 CST 2021, version=7)

JDBC Connection [HikariProxyConnection@2124562732 wrapping com.mysql.cj.jdbc.ConnectionImpl@1c93b51e] will not be managed by Spring
==>  Preparing: SELECT user_id,create_time,psw,name,update_time,version FROM tb_user WHERE user_id=? 
==> Parameters: 7(Integer)
<==    Columns: user_id, create_time, psw, name, update_time, version
<==        Row: 7, null, ycy0401, ted, 2021-11-22 12:46:31, 6
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6949e948]
更新前:tb_user(userId=7, name=ted, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:46:31 CST 2021, version=6)
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67770b37] was not registered for synchronization because synchronization is not active
2021-11-22 20:46:48.943  INFO 18248 --- [           main] s.k.t.handler.MyMetaHanlder              : 更新数据填充....
JDBC Connection [HikariProxyConnection@33389111 wrapping com.mysql.cj.jdbc.ConnectionImpl@1c93b51e] will not be managed by Spring
==>  Preparing: UPDATE tb_user SET psw=?, name=?, update_time=?, version=? WHERE user_id=? AND version=? 
==> Parameters: ycy0401(String), ted1(String), 2021-11-22 20:46:48.943(Timestamp), 7(Integer), 7(Long), 6(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67770b37]
更新后:tb_user(userId=7, name=ted1, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:46:31 CST 2021, version=7)

2)失败的测试案例(模拟多线程

    @Test
    void TestOptimistLock() {
        tb_user user1 = userMapper.selectById(7);
        System.out.println("更新前:"+user1);
        user1.setName("xyc");
        // 模拟多线程,线程1被打断,线程2获取执行权
        tb_user user2 = userMapper.selectById(7);
        user2.setName("sxf");
        user2.setPsw("yps0401");
        userMapper.updateById(user2);
        System.out.println(user2);
        // 线程1执行
        System.out.println(user1);
        userMapper.updateById(user1);
    }
JDBC Connection [HikariProxyConnection@1182469998 wrapping com.mysql.cj.jdbc.ConnectionImpl@474179fa] will not be managed by Spring
==>  Preparing: SELECT user_id,create_time,psw,name,update_time,version FROM tb_user WHERE user_id=? 
==> Parameters: 7(Integer)
<==    Columns: user_id, create_time, psw, name, update_time, version
<==        Row: 7, null, ycy0401, ted1, 2021-11-22 12:47:57, 8
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66236a0a]
更新前:tb_user(userId=7, name=ted1, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:47:57 CST 2021, version=8)
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67770b37] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@7508078 wrapping com.mysql.cj.jdbc.ConnectionImpl@474179fa] will not be managed by Spring
==>  Preparing: SELECT user_id,create_time,psw,name,update_time,version FROM tb_user WHERE user_id=? 
==> Parameters: 7(Integer)
<==    Columns: user_id, create_time, psw, name, update_time, version
<==        Row: 7, null, ycy0401, ted1, 2021-11-22 12:47:57, 8
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67770b37]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@73c31181] was not registered for synchronization because synchronization is not active
2021-11-22 20:48:46.472  INFO 21072 --- [           main] s.k.t.handler.MyMetaHanlder              : 更新数据填充....
JDBC Connection [HikariProxyConnection@1710180594 wrapping com.mysql.cj.jdbc.ConnectionImpl@474179fa] will not be managed by Spring
==>  Preparing: UPDATE tb_user SET psw=?, name=?, update_time=?, version=? WHERE user_id=? AND version=? 
==> Parameters: yps0401(String), sxf(String), 2021-11-22 20:48:46.472(Timestamp), 9(Integer), 7(Long), 8(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@73c31181]
tb_user(userId=7, name=sxf, psw=yps0401, createTime=null, updateTime=Mon Nov 22 20:47:57 CST 2021, version=9)
tb_user(userId=7, name=xyc, psw=ycy0401, createTime=null, updateTime=Mon Nov 22 20:47:57 CST 2021, version=8)
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22bf9122] was not registered for synchronization because synchronization is not active
2021-11-22 20:48:46.485  INFO 21072 --- [           main] s.k.t.handler.MyMetaHanlder              : 更新数据填充....
JDBC Connection [HikariProxyConnection@545392109 wrapping com.mysql.cj.jdbc.ConnectionImpl@474179fa] will not be managed by Spring
==>  Preparing: UPDATE tb_user SET psw=?, name=?, update_time=?, version=? WHERE user_id=? AND version=? 
==> Parameters: ycy0401(String), xyc(String), 2021-11-22 20:48:46.485(Timestamp), 9(Integer), 7(Long), 8(Integer)
<==    Updates: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22bf9122]

在模拟的线程1的更新没有成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值