Spring数据重发并发问题

问题描述 投票:1回答:1

[在使用具有spring-redis-data的多个线程时,我遇到了一个大问题,并且复制起来如此容易,以至于我认为我已经遗漏了一些琐碎的事情。]

直截了当

如果在执行保存操作时查询CrudRepository,有时(最多60%)在Redis上找不到记录。

环境

  • A docker running redis
  • 代码

    尽管可以在上面的链接中找到完整的代码,但这是主要组成部分:

    CrudRepository
    @Repository
    public interface MyEntityRepository extends CrudRepository<MyEntity, Integer> {
    
    }
    

    实体
    @RedisHash("my-entity")
    public class MyEntity implements Serializable {
    
        @Id
        private int id1;
    
        private double attribute1;
        private String attribute2;
        private String attribute3;
    

    控制器
        @GetMapping( "/my-endpoint")
        public ResponseEntity<?> myEndpoint () {
    
            MyEntity myEntity = new MyEntity();
            myEntity.setAttribute1(0.7);
            myEntity.setAttribute2("attr2");
            myEntity.setAttribute3("attr3");
            myEntity.setId1(1);
    
            myEntityRepository.save(myEntity);//create it in redis
    
            logger.info("STARTED");
    
            for (int i = 0; i < 100; i++){
                new Thread(){
                    @Override
                    public void run() {
                        super.run();
    
                        myEntity.setAttribute1(Math.random());
    
                        myEntityRepository.save(myEntity); //updating the entity
    
                        Optional<MyEntity> optionalMyEntity = myEntityRepository.findById(1);
                        if (optionalMyEntity.isPresent()) {
                            logger.info("found");
                        }else{
                            logger.warning("NOT FOUND");
                        }
                    }
                }.start();
    
            }
    
            return ResponseEntity.noContent().build();
        }
    
    

    结果
    2020-05-26 07:52:53.769  INFO 30655 --- [nio-8080-exec-2] my-controller-logger                     : STARTED
    2020-05-26 07:52:53.795  INFO 30655 --- [     Thread-168] my-controller-logger                     : found
    2020-05-26 07:52:53.798  WARN 30655 --- [     Thread-174] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.798  WARN 30655 --- [     Thread-173] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.806  INFO 30655 --- [     Thread-170] my-controller-logger                     : found
    2020-05-26 07:52:53.806  WARN 30655 --- [     Thread-172] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.812  WARN 30655 --- [     Thread-175] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.814  WARN 30655 --- [     Thread-176] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.819  WARN 30655 --- [     Thread-169] my-controller-logger                     : NOT FOUND
    2020-05-26 07:52:53.826  INFO 30655 --- [     Thread-171] my-controller-logger                     : found
    2020-05-26 07:52:53.829  INFO 30655 --- [     Thread-177] my-controller-logger                     : found
    

    因此,仅使用10个线程,其中6个在db中找不到结果。

    用弹簧数据重做代替

    如上所述here用弹簧数据redis替换redis至少包含9个操作。

    第一个结论

    因此,要替换redis中的值,它必须删除哈希,索引,然后再次添加新的哈希和新的索引,也许某个线程正在执行此操作,而其他线程试图查找按索引的值,并且尚未添加该索引。

    第二个结论

    我认为带有data-redis的spring数据几乎不可能出现这样的错误,所以我想知道我对data-redis或redis的了解不多。由于redis具有并发性,我认为可能会发生一些不同的事情,但是对于所提供的示例,它看起来像是...

    先谢谢大家

    当在spring-redis-data上使用多个线程时,我遇到了一个大问题,并且复制起来如此容易,以至于我认为我已经遗漏了一些琐碎的事情。直截了当如果我查询...

    java spring multithreading concurrency spring-data-redis
    1个回答
    0
    投票

    您有一个MyEntity实例:

    © www.soinside.com 2019 - 2024. All rights reserved.