【问题标题】:Transactions on my service layer我的服务层上的交易
【发布时间】:2015-03-24 03:04:08
【问题描述】:

我有一个标记为@Transactional 的服务。唯一的问题是,我正在研究在调用 save 方法时需要提交对象的方法。

我已经从类级别删除了注释,并将除我之外的每个方法都标记为@Transactional(DAO 也标记为@Transactional)。我确实看到我的信息现在正在按我想要的方式立即保存,但是当我尝试执行 findBy 时,我得到“线程中不存在会话”异常。

有人知道这个问题以及如何解决它吗?

【问题讨论】:

    标签: hibernate transactions hibernate-session


    【解决方案1】:

    因此,我将不得不对您的方法正在做什么做一些有根据的猜测,因为您没有向我们提供有关您的服务类和 DAO 正在做什么的任何细节。

    首先,使用@Transactional 标记您的服务方法是最佳实践,因为您的服务类应该管理您的事务会话。您的 DAO 应该仅用于访问数据库并以表单形式返回您的对象,以便您可以使用它们。会话不是 DAO 应该担心的事情。

    现在我猜你的服务类看起来像这样:

    @Transactional
    public void saveOrUpdateFoo(Foo foo){
        fooDao.saveOrUpdate(foo);
    }
    
    @Transactional
    public Foo manipulateFoo(Foo foo){
        //Do stuff to your Foo object that you want to be changed.
        saveOrUpdateFoo(foo);
        //Database hasn't actually changed yet.
        foo = fooDao.findBy(foo.getFooId());
        //nothing will change here.
    }
    

    要了解为什么当您调用saveOrUpdateFoo(foo) 时您的数据库实际上并没有改变,您需要了解@Transactional 批注实际上导致Hibernate 的原因。当您将方法标记为 @Transactional 时,您是在告诉 Hibernate,此方法中的所有内容都需要在单个数据库会话中发生,并且如果出现问题,它应该回滚。

    为了促进这一点,当您在 DAO 中调用 currentSession().save(foo); 时(我假设您正在这样做),Hibernate 会获取您的对象,并在内存中更新该对象的本地“克隆”。 (这实际上不是它的工作原理,只是想象一下,当事务启动时,Hibernate 基于数据库保留它自己的对象副本,当您调用 save/update 时,它​​会更改这些副本)

    当您的@Transactional 方法退出时,Hibernate 会将这些更改刷新到数据库,这是您的数据库状态实际更改的时候。如果这个对象是一个新对象(因为在数据库中必须创建一个新记录),当您调用saveOrUpdateFoo 时,Hibernate 应该使用保存数据库时将使用的值更新它管理的任何 ID 字段。保存对象后,您不需要“重新获取”您的对象,它应该处于一种状态,就好像您实际上已将 INSERT'd 放入数据库,然后 SELECT'd 再次将其保存,没有更改实际上被持久化到数据库中。

    这应该不是问题,除非您尝试在另一个线程中从数据库中获取对象,而这一切都在进行中,在这种情况下,您需要重新设计您的服务类,这样就不会发生。

    如果这不能解决您的问题,请发布您的服务类和 DAO,并说明您实际尝试做什么。

    【讨论】:

      猜你喜欢
      • 2013-04-07
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 2012-04-21
      • 1970-01-01
      • 2023-01-12
      • 2014-10-19
      • 1970-01-01
      相关资源
      最近更新 更多