0

我正在尝试并行进行提要处理,从平面文件中提取数据并填充一些存储库项。

代码有点像下面。在生产中,它非常慢,通过 Dynatrace 进行调查时,我可以看到 getPropertyValue 方法调用中的锁定时间比平时要大(总时间的 70% 用于锁定)

在使用 dynatrace 深入研究 getPropertyvalue 方法时,我可以看到这个方法 GSAItemDescriptor.putItemInCache 是罪魁祸首。我怀疑此方法中有同步块导致线程等待。

有什么办法破解这个?

...
        try {
            inventoryIdsList.parallelStream().forEach((item)->{
                final String lockString = item.split("_")[0] + "_inventory_index_update";
                final String lock = lockString.intern();
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    synchronized (lock) {       
                        if(doIncrementalIndexInNewTransaction(item)) {
                            vlogDebug("Success indexing done inventoryId={0}",item);
                        } else {
                            vlogError("Failed_to_index inventoryId={0}",item);
                        }   
                    }
                },pool);
                futures.add(future); 
            }); 

            
                CompletableFuture<Void> allfutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
                allfutures.get();
            } catch (Exception e) {
                vlogError(e,"Error while executing async.");
            }
            
...
void doIncrementalIndexInNewTransaction(inventoryId){
    TransactionDemarcation td = new TransactionDemarcation();
        boolean success = false;
        try {
            vlogDebug("Processig inventory item idexing inventoryId={0}",inventoryId);
            td.begin(getTransactionManager(),TransactionDemarcation.REQUIRES_NEW);
            RepositoryItem inventoryRI = getInventoryRepository().getItem(inventoryId,"inventory");
            if(inventoryRI != null){
                String inventoryUpdateStore= (String) inventoryRI.getPropertyValue("locationId");
                String skuId =(String)inventoryRI.getPropertyValue("skuId");
                MutableRepositoryItem skuRepositoryItem= (MutableRepositoryItem) mutableRepository.getItemForUpdate(skuId, "sku");
                ...
                Some other operations
                ...
                skuRepositoryItem.setPropertyValue("lastUpdated",System.currentMillis());
            }
            vlogDebug("Success inventoryId={0}",inventoryId);
            return true;
        } catch (Exception e) {
            vlogError(e,"Exception occured while processing inventoryId={0}",inventoryId);
            success = false;
        } finally {
            try {
                td.end(!success);
            } catch (Exception e) {
                vlogError(e,"Unable to end transaction id={0} \n inventoryId={1}", td,inventoryId);
            }
        }
        return success;
}

动态跟踪数据。 浅蓝色表示锁定时间

提前致谢。

4

0 回答 0