【问题标题】:Should I commit hibernate transaction before calling session.evict(obj)我应该在调用 session.evict(obj) 之前提交休眠事务吗
【发布时间】:2016-02-19 04:52:55
【问题描述】:

保存后何时应在休眠状态下提交事务。是在我调用 session.evict(obj) 之前还是之后。目前我的代码看起来像这样(只有必需的部分)。

Session session = connector.getSession();
Transaction tx = session.beginTransaction();
try {
        Criteria crit = session.createCriteria(ST_CODE_SETTINGS_STORE.class).add(Restrictions.eq("TYPE", "issueno"));
        List<ST_CODE_SETTINGS_STORE> ls = crit.list();
        if (ls.size() < 1) {
            session.save(st_code_settings_store);
            session.evict(st_code_settings_store);
            msg = "insert";
        } 
        else {
            Long Id = null;
            ST_CODE_SETTINGS_STORE st_code_settings_store1 = ls.get(0);
            Id = st_code_settings_store1.getCODE_ID();

            Object o = session.get(ST_CODE_SETTINGS_STORE.class, Id);
            ST_CODE_SETTINGS_STORE update = (ST_CODE_SETTINGS_STORE) o;
            session.update(update);
        }
        tx.commit();
    } catch (Exception e) {
        if (tx != null) {
            tx.rollback();
        }
        System.out.println("Error: " + e.getMessage());
        connector.printStack(e);
        throw e;
    } finally {
        session.close();
    }

有时如果我在驱逐后提交,数据不会保存在数据库中。这是正确的编码方式吗??

【问题讨论】:

标签: java transactions hibernate-session


【解决方案1】:

evict() 方法从会话缓存中删除单个对象。 所以 在调用 evict() 之前,对象应该在 Session 中 缓存。因此,如果您第一次保存对象,则必须保存 对象通过 Session.save(object). 后续更新调用应该 遵循 session.saveOrUpdate(object) 或 session.update(object) 在调用 evict() 从缓存中删除加载的对象之前。(reference)

来自Hibernate Docs

结束会话通常涉及四个不同的阶段:

  • 刷新会话
  • 提交事务
  • 关闭会话
  • 处理异常

不要使用反模式 session-per-user-session 或 每个应用程序的会话(但是,这种情况很少见 规则)。以下一些问题也可能出现在 推荐的模式,因此请确保您了解其中的含义 在做出设计决定之前:

  • 会话不是线程安全的。可以同时工作的东西,比如 HTTP 请求、会话 bean 或 Swing 工作者,将导致竞争条件 如果会话实例是共享的。如果你保持你的休眠会话 你的 HttpSession (这将在本章后面讨论),你应该 考虑同步访问您的 Http 会话。否则,用户 点击重新加载速度足够快可以在两个中使用相同的会话 并发运行的线程。

  • Hibernate 抛出的异常意味着 你必须回滚你的数据库事务并关闭会话 立即(这将在本章后面更详细地讨论)。 如果您的 Session 绑定到应用程序,则必须停止 应用。回滚数据库事务不会把你的 业务对象恢复到它们开始时的状态 交易。这意味着数据库状态和业务 对象将不同步。通常这不是问题,因为 异常是不可恢复的,你必须在之后重新开始 无论如何都要回滚。

  • Session 缓存一个对象中的每个对象 持久状态(由 Hibernate 监视和检查脏状态)。 如果您长时间保持打开状态或只是加载太多数据,它 将无限增长,直到您收到 OutOfMemoryException。 一个 解决方案是调用 clear() 和 evict() 来管理 Session 缓存, 但如果您需要大量数据,则应考虑使用存储过程 操作。

【讨论】:

    猜你喜欢
    • 2018-05-06
    • 2016-04-24
    • 2011-04-05
    • 2013-05-04
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    相关资源
    最近更新 更多