我正在尝试并行进行提要处理,从平面文件中提取数据并填充一些存储库项。
代码有点像下面。在生产中,它非常慢,通过 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;
}
提前致谢。