如何正确使用休眠

时间:2012-09-09 22:21:06

标签: java hibernate

每次我想用hibernate做一些动作时,我的应用程序中都有以下代码:

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(obj); //or delete, update etc.
session.getTransaction().commit();
session.close();

这当然不是一个好习惯。访问hibernate的最佳方法是什么,而不是这样的情况?我应该使用一些包含执行相同工作的静态方法的“Util”类吗?也许单身更好?我还需要在线程或SwingWorker中包装此代码,以便在访问数据库时不冻结我的GUI。

2 个答案:

答案 0 :(得分:0)

是的,那段代码非常糟糕。

  1. 它为每个数据库访问打开一个事务。这是低效的,可能是不正确的(通常,整组动作需要是原子的。例如,考虑

    public void buy(String accountId) {
        Account account = load(accountId);
        account.balance -= 100;
        save(account);
    }
    

    如果加载和保存在他们自己的交易中,并且一些恶意用户同时购买了2个项目,则可能发生以下情况:

    • 主题1读取余额(= 1000)
    • 线程2读取余额(= 1000)
    • 线程1写入余额(= 900)
    • 线程2写入余额(= 900)

    所以用户买了两次,但只付了一次; - )

  2. 如果save()抛出异常,它就不会完成事务。事实上,交易将无限期地保持开放,包括它持有的所有锁......

  3. 这些复杂性是大多数人以声明方式划分交易而不是重新发明方形轮的原因,例如使用SpringEJB

答案 1 :(得分:0)

我强烈建议您阅读Hibernate网站上的this文章。

对于考虑在Hibernate中使用会话和事务的最佳方法的人来说,这篇文章是必须的。

基本上,最好的设计模式将取决于您的交易管理策略 已选择(jdbc,jta)和应用交易的模式(程序/声明)

正如meriton已经指出的那样,代码中每个方法的打开和关闭事务(假设有几个这样的方法按顺序工作以形成原子操作)是反模式。这篇文章也将在文章中详细讨论。