繁体   English   中英

@Transactional方法调用-我们应该将对象作为参数传递吗?

[英]@Transactional Method Calling - should we pass objects as parameters?

@Transactional
public void schoolProcessing{
    //some logic here
    save(student);  //student is now managed
    //Calling update student
     updateStudent(student) or  updateStudent();
    //which of the above is the correct way 
}

public void updateStudent(Student student) {
    //some student update logic
}

在JPA中从@Transactional方法调用方法时,是否应将托管实体作为参数传递? 还是由于将其标记为@ Transactional,JPA无缝处理所有持久性,就像从@Transactional调用的所有方法都在同一个方法中一样?

为了明确起见,以上代码在各个方面是否与以下代码相同。

@Transactional
public void schoolProcessing{
    //some logic here
    save(student);  //student is now managed

    //some student update logic
}

我认为这是一个基本问题,但已经看过其他问题,但无法澄清。 谢谢。

简短的答案:两者都会起作用

长答案:

关于@Transactional和事务传播,有很多细节。 以下是有关大多数开发人员使用的最简单方案的一些信息。

当组件/服务/控制器具有@Transactional Spring会将其包装在一个代理(思维装饰器模式)中,该代理将创建线程本地状态,以容纳事务信息并将其链接到@PersistenceContext EntityManagers 当代理完成对@Transactional方法的调用时,它将提交事务。 由于此方法使用线程本地状态,因此在@Transactional方法内部使用的任何@PersistenceContext注释的EntityManager或它调用的任何方法,即使其他bean中的方法也将共享相同的事务和持久性上下文。

为了更好地了解更新,让我们看看在JPA中加载实体时会发生什么。 当您加载实体时,持久性上下文会保存一个副本,并且在事务提交时,它将遍历所有托管实体,并将它们与加载时的副本进行比较,并以此为基础确定要发送到哪个更新语句。数据库。 因此,当您加载实体并对其进行修改时,您无需执行任何操作(除了让事务提交),即可更新数据库。 当您保留一个新实体时,将其添加到托管实体的内部集合中,并且如果将该实体发送给修改它的方法,则只要修改发生在事务提交之前,它也将最终存储在数据库中,并且实体变得分离。

这只是冰山一角,一旦您开始谈论不同的传播类型,手动调用刷新或触发查询前刷新的查询,就会变得非常复杂。 以我的经验,JPA是最被低估的Java技术之一,从表面上看它是如此简单,但是如果您不了解基本原理,则可以花几天的时间来了解/调试所得到的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM