我有以下情景:
我有一个控制器,它基于路径变量调用不同的服务。
在每个服务中都有一个事务性方法,其中发生了一些导入逻辑(调用一个外部API,获取CSV文件,解析它,将其转换为实体并将其保存在数据库中)。
此外,在每项服务中,我想要保存有多少实体将被更新、插入和删除的统计数据。出于这个原因,我使用org.hibernate.SessionFactory
。我如何使用它的一个例子是:
@Service
@Slf4j
public class MarketReportImporterImpl extends Support implements MarketReportImporter {
@Override
@Transactional
public void importMarketReports(ImporterLog importerLog) {
try {
String export = getCsvFile();
Session session = getCurrentSessionAndClearSessionFactoryStatistics();
// parse the csv and save the entities
flushSession(session);
setSuccessfulImport(session, importerLog);
} catch (Exception e) {
log.error("Failed to import market reports. Unable to parse export", e);
getTelemetryClient().trackException(e);
importerLogService.setFailedImport(importerLog, e.getMessage());
}
}
方法getCurrentSessionAndClearSessionFactoryStatistics()
和setSuccessfulImport(session, importerLog);
位于Support
类中:
@Component
public abstract class Support {
private final ImporterLogService importerLogService;
@PersistenceContext
private EntityManager entityManager;
public Support(ImporterLogService importerLogService) {
this.importerLogService = importerLogService;
}
public void flushSession(Session session) {
session.flush();
}
public void setSuccessfulImport(Session session, ImporterLog importerLog) {
Statistics statistics = session.getSessionFactory().getStatistics();
int entityInsertCount = (int) statistics.getEntityInsertCount();
int entityDeleteCount = (int) statistics.getEntityDeleteCount();
int entityUpdateCount = (int) statistics.getEntityUpdateCount();
importerLogService.setSuccessfulImport(importerLog, entityUpdateCount, entityDeleteCount, entityInsertCount);
}
public Session getCurrentSessionAndClearSessionFactoryStatistics() {
Session session = entityManager.unwrap(Session.class);
SessionFactory sessionFactory = session.getSessionFactory();
sessionFactory.getStatistics().clear();
return session;
}
当为一个进口商调用它时,这是非常好的。但是,如果我从前台快速调用两个导入器(意味着两个线程并行运行),结果中将会有混合。session.getSessionFactory().getStatistics();
将有来自第一个进口商和第二个进口商的混合结果,我希望只有当前会话的明确结果。例如,服务A和服务B并行运行,我在服务A中保存aa
类型的实体,在服务B中保存bb
类型的实体。在每个服务中,我想知道有多少实体被保存、更新或删除,这意味着在服务A->有多少aa
类型的实体,在服务B->有多少类型的bb
。据我所知,每个线程都应该自己打开一个会话,然后对于每个会话,我应该得到正确的会话工厂和正确的结果。但是,正如我猜测的那样(在此语句中不确定),它属于每个会话,这就是我有MIX结果的原因。
我的问题是,是否有办法以某种方式分离会话工厂,并清楚地了解哪个实体即使在多线程环境中也要保存、删除和更新多少次。
1条答案
按热度按时间sqxo8psd1#
如果您需要会话的统计信息,那么对
session
调用getStatistics()
方法,它将为您提供SessionStatistics
。SessionFactory
应该只存在一次,并且存在跨所有会话的统计信息。