【问题标题】:@Transactional drastically slows down Rest API@Transactional 大大减慢了 Rest API
【发布时间】:2018-10-09 07:28:48
【问题描述】:

Service 在构造函数中从 DB 中获取数据并将其存储在 HashMap 中,然后从 HashMap 返回数据。请看:

@RestController
@RequestMapping("/scheduler/api")
@Transactional(readOnly = true, transactionManager = "cnmdbTm")
public class RestApiController {

    private final Set<String> cache;

    @Autowired
    public RestApiController(CNMDBFqdnRepository cnmdbRepository, CNMTSFqdnRepository cnmtsRepository) {
        cache = new HashSet<>();
        cache.addAll(getAllFqdn(cnmdbRepository.findAllFqdn()));
        cache.addAll(getAllFqdn(cnmtsRepository.findAllFqdn()));
    }

    @RequestMapping(value = "/fqdn", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public List<SchedulerRestDto> checkFqdn(@RequestBody List<SchedulerRestDto> queryList) throws ExecutionException {
        for (SchedulerRestDto item : queryList) {
            item.setFound(1);
            if (!cache.contains(item.getFqdn())) {
                item.setFound(0);
            }
        }
        return queryList;
    }

    private Set<String> getAllFqdn(List<String> fqdnList) {
        Set<String> result = new HashSet<>();
        for (String fqdn : fqdnList) {
            result.add(fqdn);
        }
        return result;
    }

}

但我总是在大约 2 秒内得到结果。我认为从 DB 获得的 35K 字符串有点慢。

我试图找出问题所在。我将序列化的HashMap 存储到文件中,并将构造函数修改为:

@Autowired
public RestApiController(CNMDBFqdnRepository cnmdbRepository, CNMTSFqdnRepository cnmtsRepository) {
    try (final InputStream fis = getResourceAsStream("cache-hashset.ser");
         final ObjectInputStream ois = new ObjectInputStream(fis)) {
        cache = (Set<String>) ois.readObject();
    }
}

该服务在不到 100 毫秒后返回结果。

我认为它与 DB 有关,但我不知道如何修复它。

有什么想法吗?

【问题讨论】:

    标签: java rest spring-boot spring-data


    【解决方案1】:

    经过几个小时的实验,我意识到主要原因是类上的 @Transactional 注释。

    当我在方法上移动此注释时,服务返回响应更快。在我的最终决定中,我将此注释移至另一个类。新的构造函数是

    @Autowired
    public RestApiController(FqdnService fqdnService, SqsService sqsService) {
        Objects.requireNonNull(fqdnService);
        cache = fqdnService.getCache();
    }
    

    代码更简洁,没有任何性能问题。

    【讨论】:

      猜你喜欢
      • 2018-02-23
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-31
      • 1970-01-01
      • 2017-08-20
      相关资源
      最近更新 更多