> Java > java지도 시간 > MyBatisPlus+SpringBoot를 사용하여 낙관적 잠금 기능을 구현하는 방법

MyBatisPlus+SpringBoot를 사용하여 낙관적 잠금 기능을 구현하는 방법

WBOY
풀어 주다: 2023-05-11 20:46:11
앞으로
928명이 탐색했습니다.

    1. 쇼핑몰 데이터가 일치하지 않는 시나리오

    쇼핑몰에 제품이 있는 경우 원가는 80위안, 판매가는 100위안입니다. 관리자는 먼저 Xiao Li에게 상품 가격을 50위안 인상해야 한다고 알렸습니다. Xiao Li는 게임을 하다가 한 시간 동안 지연되었습니다. 정확히 한 시간 후, 관리자는 제품 가격이 150위안으로 올랐는데, 이는 너무 높아 판매에 영향을 미칠 수 있다고 느꼈습니다. 또한 Xiao Wang에게 제품 가격을 30위안 인하하겠다고 알립니다.

    현재 Xiao Li와 Xiao Wang은 제품 백엔드 시스템을 동시에 운영하고 있습니다. Xiao Li가 작동할 때 시스템은 먼저 제품 가격 100위안을 인출하고 Xiao Wang도 작동하며 제품 가격도 100위안을 인출합니다. Xiao Li는 가격에 50위안을 추가하고 100+50=150위안을 데이터베이스에 저장했습니다. Xiao Wang은 제품을 30위안 줄이고 100-30=70위안을 데이터베이스에 저장했습니다. 예, 잠금 장치가 없으면 Xiao Li의 작업은 Xiao Wang의 작업에 완전히 포함됩니다.

    현재 제품 가격은 70위안으로 원가보다 10위안 저렴합니다. 몇 분 만에 이 제품의 1,000개 이상의 품목이 빠르게 판매되었고 사장은 10,000위안 이상의 손실을 입었습니다.

    두 번째, 이 프로세스를 보여줍니다

    1. 데이터베이스에 제품 테이블을 추가합니다

    CREATE TABLE product
    (
        id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
        name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
        price INT(11) DEFAULT 0 COMMENT '价格',
        version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
        PRIMARY KEY (id)
    );
    
    INSERT INTO product (id, NAME, price) VALUES (1, '笔记本', 100);
    로그인 후 복사

    2. 엔터티 클래스를 생성합니다

    @Data
    public class Product {
        private Long id;
        private String name;
        private Integer price;
        private Integer version;
    }
    로그인 후 복사

    3. 테스트를 수행합니다

    public interface ProductMapper extends BaseMapper<Product> {
        
    }
    로그인 후 복사

    . 70위안, 관리자가 예상한 120위안이 달라 손실이 발생합니다. 이러한 이상 현상이 발생하지 않도록 하려면 어떻게 해야 할까요? 해결책은 낙관적 잠금을 사용하는 것입니다

    3. 낙관적 잠금 방식

    버전 필드를 데이터베이스에 추가하세요. : 레코드를 검색할 때 현재 버전을 가져옵니다

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ProductVersionTest {
    	@Resource
    	private ProductMapper productMapper;
    	
    	@Test
    	public void testProductUpdate() {
    	
    	    //1、小李
    	    Product p1 = productMapper.selectById(1L);
    	
    	    //2、小王
    	    Product p2 = productMapper.selectById(1L);
    	
    	    //3、小李将价格加了50元,存入了数据库
    	    p1.setPrice(p1.getPrice() + 50);
    	    int result1 = productMapper.updateById(p1);
    	    System.out.println("小李修改结果:" + result1);
    	
    	    //4、小王将商品减了30元,存入了数据库
    	    p2.setPrice(p2.getPrice() - 30);
    	    int result2 = productMapper.updateById(p2);
    	    System.out.println("小王修改结果:" + result2);
    	
    	    //最后的结果
    	    Product p3 = productMapper.selectById(1L);
    	    System.out.println("最后的结果:" + p3.getPrice());
    	}
    }
    로그인 후 복사

    업데이트할 때 버전 + 1. where 문의 버전이 올바르지 않으면 업데이트가 실패합니다

    SELECT id,`name`,price,`version` FROM product WHERE id=1
    로그인 후 복사

    4. 낙관적 잠금 구현 프로세스

    1.

    @Version 주석 추가

    UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND `version`=1
    로그인 후 복사

    2. 낙관적 잠금 플러그인 추가

    @Version
    private Integer version;
    로그인 후 복사

    3. 프로세스 최적화

    (두 번째 데이터 업데이트가 성공했는지 확인하고, 그렇지 않은 경우 업데이트를 위해 데이터를 다시 가져옵니다.)

    @Configuration
    //@MapperScan("com.koo.modules.*.dao")
    public class MybatisPlusConfig {
    
        /**
         * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
         */
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            //实现乐观锁,保证数据的准确性
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            return interceptor;
        }
    
        @Bean
        public ConfigurationCustomizer configurationCustomizer() {
            return configuration -> configuration.setUseDeprecatedExecutor(false);
        }
    
    }
    로그인 후 복사

    출력 결과는 120이며, 데이터가 정확합니다

    위 내용은 MyBatisPlus+SpringBoot를 사용하여 낙관적 잠금 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:yisu.com
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿