springboot+mybatis-plus实现“乐观锁”

乐观锁

什么是乐观锁:是针对一些特定问题的解决方案,主要解决丢失更新问题

假如有一条数据同时被两个及以上的人进行修改,这个时候就会产生丢失更新问题。

譬如:小明想修改一条数据的money字段,他看到的money是500,他应该500太少想多加一点,改变成1000,但是小红也想改变money,她因为500太少想少加一点,改成600。小明的修改先发生,他们都是由500进行修改的,按理来说,小红应该是根据小明修改后的1000来修改成600,但是事实不是。这就叫丢失更新。

解决方案:

1悲观锁:某一个进行对一条数据进行操作时,其它人不可以操作这条数据,视为串行操作,他的          效率比较低
2乐观锁:新建一个字段为version,再进行操作时给判断版本号的值,若version一样才可以        操作数据u,否则不行

乐观锁的实现:

如图,在这个表中添加一个version字段,并且在实体类中添加这个属性。

package com.atguigu.mpdemo1010.enitty;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;
import java.util.Date;

@Data
public class User {

  @TableId(type = IdType.ID_WORKER)
  private Long id;
  private String name;
  private long age;
  private String email;
  @TableField(fill = FieldFill.INSERT)
  private Date createTime;
  @TableField(fill = FieldFill.INSERT_UPDATE)
  private Date updateTime;
  private Integer version;//版本号

  @Override
  public String toString() {
    return "User{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            ", email='" + email + '\'' +
            ", createTime=" + createTime +
            ", updateTime=" + updateTime +
            ", version=" + version +
            '}';
  }
}

 在实体类中的version属性上添加一个注解:@Version

 配置一个乐观锁的插件:

mybatis-plus中提供了spring和springboot的插件配置:

spring:

利用bean来进行配置

<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor" id="optimisticLockerInnerInterceptor"/>

<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors">
        <list>
            <ref bean="optimisticLockerInnerInterceptor"/>
        </list>
    </property>
</bean>

springboot:创建这个类,并使用@Bean来实现乐观锁

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

如何创建这个插件类:

方法一:直接将这个放到springboot中的启动类中

@MapperScan("com.atguigu.mpdemo1010.mapper")
@SpringBootApplication
public class Mpdemo1010Application {

    public static void main(String[] args) {
        SpringApplication.run(Mpdemo1010Application.class, args);
    }

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

方法二:我们把这个配置插件放到专门的配置类中,让spring帮我自动管理

package com.atguigu.mpdemo1010.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Mpconfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

测试:

插入一条新的数据,让他再被插入时version自动赋值为1

(自动赋值在mybatis_plus文章中)

mybatis实现自填充

@Test
public void add()
{
    User user = new User();
    user.setName("titi");
    user.setAge(22);
    user.setEmail("302064225");
    Integer insert = userMapper.insert(user);
    System.out.println("insert:"+insert);
}

运行结果:

 再通过id进行查询并修改:

  @Test
    public void testlgs()
    {
//        根据id查询
        User user = userMapper.selectById("1508710305724223490");
        System.out.println("乐观锁:"+user);
        Scanner sc  = new Scanner(System.in);
        sc.nextInt();
        user.setName("乐观锁");
        user.setAge(11);
        Integer row = userMapper.updateById(user);
    }

运行结果:

因为我在上面的testlgs方法中添加了输入语句,可以暂停程序的运行,这时我们去强行修改user表中的1508710305724223490为id的数据的version为3,然后再继续运行程序,看一下不同的效果。

运行结果如下:

我们看到他的update是为0的就说明没有数据更新成功,所以他没有更新

我们再看一下数据的库的值,是不是还是我们强行修改后的3

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值