CREATE TABLE `sale` (
`id` int NOT NULL,
`name` varchar(45) DEFAULT NULL,
`price` int DEFAULT '0',
`version` int DEFAULT '0',
PRIMARY KEY (`id`)
)
package com.xdu.mybatisplus.pojo;
import lombok.Data;
@Data
public class Sale {
private Integer id;
private String name;
private Integer price;
private Integer version;
}
package com.xdu.mybatisplus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xdu.mybatisplus.pojo.Sale;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SaleMapper extends BaseMapper<Sale> {
}
不加乐观锁
老板让小李将原价为100的商品的价格增加50,然后又让小王将价格在小李的基础上减少30,由于两人同时操作,造成了结果错误。
package com.xdu.mybatisplus;
import com.xdu.mybatisplus.mapper.SaleMapper;
import com.xdu.mybatisplus.pojo.Sale;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MyBatisPlusTest {
@Autowired
private SaleMapper saleMapper;
@Test
public void testLock(){
//小李查询商品价格
Sale saleLi = saleMapper.selectById(1);
System.out.println("小李查询的商品价格:" + saleLi.getPrice()); //100
//小王查询商品价格
Sale saleWang = saleMapper.selectById(1);
System.out.println("小李查询的商品价格:" + saleWang.getPrice()); //100
//小李将价格+50
saleLi.setPrice(saleLi.getPrice() + 50);
saleMapper.updateById(saleLi);
//小王将价格-30
saleWang.setPrice(saleWang.getPrice() - 30);
saleMapper.updateById(saleWang);
//老板查询商品价格
Sale saleBoss = saleMapper.selectById(1);
System.out.println("老板查询的商品价格:" + saleBoss.getPrice()); //70
//结果需要为120,但是结果是70
}
}
加乐观锁
需要使用乐观锁来处理上述冲突
1. 添加乐观锁注解
package com.xdu.mybatisplus.pojo;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
@Data
public class Sale {
private Integer id;
private String name;
private Integer price;
@Version //标识乐观锁版本号字段
private Integer version;
}
2. 添加乐观锁插件
在MyBatisPlus的配置类中添加乐观锁插件
package com.xdu.mybatisplus.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
3. 测试
添加乐观锁之后执行最初的代码,结果为150,因为小李在修改完价格之后,version由最初的0变成了1,当小王去修改价格的时候,由于version=1,所以不能执行修改操作。
对上述代码进行修改如下:
package com.xdu.mybatisplus;
import com.xdu.mybatisplus.mapper.SaleMapper;
import com.xdu.mybatisplus.pojo.Sale;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MyBatisPlusTest {
@Autowired
private SaleMapper saleMapper;
@Test
public void testLock(){
//小李查询商品价格
Sale saleLi = saleMapper.selectById(1);
System.out.println("小李查询的商品价格:" + saleLi.getPrice()); //100
//小王查询商品价格
Sale saleWang = saleMapper.selectById(1);
System.out.println("小王查询的商品价格:" + saleWang.getPrice()); //100
//小李将价格+50
saleLi.setPrice(saleLi.getPrice() + 50);
saleMapper.updateById(saleLi);
//小王将价格-30
saleWang.setPrice(saleWang.getPrice() - 30);
int result = saleMapper.updateById(saleWang);
if(result == 0){ //说明没有执行成功修改操作
//重新获取
Sale saleNew = saleMapper.selectById(1);
System.out.println("重新获取的商品价格:" + saleNew.getPrice()); //150
saleNew.setPrice(saleNew.getPrice() - 30);
saleMapper.updateById(saleNew);
}
//老板查询商品价格
Sale saleBoss = saleMapper.selectById(1);
System.out.println("老板查询的商品价格:" + saleBoss.getPrice()); //120
}
}