如何在 Hibernate 会话中使用全局临时表?

Posted

技术标签:

【中文标题】如何在 Hibernate 会话中使用全局临时表?【英文标题】:How can I use a global temporary table with Hibernate session? 【发布时间】:2015-04-18 00:42:21 【问题描述】:

我在我的数据库中创建了一个全局临时表。我正在使用它将少量处理过的数据合并到一个更大的表中。

我正在写入临时表并在一次响应请求的服务中从其中删除。每个请求都应该使用不同的数据库会话,以便数据不会在请求之间发生冲突。也就是说,我希望数据库会话在请求之间关闭并重新打开,以便一个请求的数据对下一个请求的数据不可见。

我们的应用程序使用 Hibernate 来管理数据库会话。我发现很难从文档中理解数据库会话和休眠会话之间的关系——但即使我调用 openSession() 然后调用 session.close,Hibernate 似乎也在我的课堂上给了我相同的数据库会话() 请求之间。我写了一些测试代码来测试这个行为。

public void testTemporaryTable() 
    Session session = sessionFactory.openSession();
    writeToTemporary(session);
    System.out.println(countDataInTemporary(session));
    ...
    mergeFromTemporay(session);
    // Here I'm hoping for a closed db session, to make the data disappear:
    session.close();


当我从同一个主线程运行两次时,我第一次在临时表中看到 70,000 个结果。第二次运行它,我看到了 140,000 个结果。如果数据库会话实际上已经关闭并且会话工厂 openSession 给了我一个新的数据库会话,那么我第二次应该只能看到 70,000 个结果。

我希望有一个简单的解决方案,因为临时表可以更轻松地管理要处理的大量数据。


我的发现:

Hibernate 会话与数据库会话不是一一对应的。在我们的系统中,我们使用一个连接池,而 Hibernate 会话使用来自池的连接。使用连接池和休眠会话的好处是减少了创建连接的需要,这很昂贵。

解决办法:

在同一服务线程内的使用之间截断临时表。

为什么是临时表?

服务关闭时会删除数据,这发生在用户会话之间。 如果服务在处理过程中中止,则数据将被删除。不幸的是,这种情况经常发生。

【问题讨论】:

【参考方案1】:

Hibernate 会话与数据库会话不是一一对应的。因此,要使用临时表而不保证数据库会话将在后续休眠会话之间更新,则应将其截断以删除数据。这是一种低成本的操作。

【讨论】:

以上是关于如何在 Hibernate 会话中使用全局临时表?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL创建临时表?

SQL Server 表变量和临时表的区别

Oracle全局临时表/PHP交互题

使用全局临时表的真实场景

SQL SERVER 临时表能使用EXEC SP_spaceused 查询表大小么

linux怎么修改mysql数据库临时表空间大小