获取每个线程每个会话使用org.hibernate.SessionFactory的实体的插入、更新和删除次数

zf9nrax1  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(138)

我有以下情景:
我有一个控制器,它基于路径变量调用不同的服务。
在每个服务中都有一个事务性方法,其中发生了一些导入逻辑(调用一个外部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结果的原因。
我的问题是,是否有办法以某种方式分离会话工厂,并清楚地了解哪个实体即使在多线程环境中也要保存、删除和更新多少次。

sqxo8psd

sqxo8psd1#

如果您需要会话的统计信息,那么对session调用getStatistics()方法,它将为您提供SessionStatisticsSessionFactory应该只存在一次,并且存在跨所有会话的统计信息。

相关问题