简体   繁体   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
}

While calling methods from @Transactional methods in JPA, should we pass the managed entities as parameters ? 在JPA中从@Transactional方法调用方法时,是否应将托管实体作为参数传递? Or is it that since this is marked as @Transactional, JPA seamless handles all the persistence as if all the methods being called from @Transactional were within the same method ? 还是由于将其标记为@ Transactional,JPA无缝处理所有持久性,就像从@Transactional调用的所有方法都在同一个方法中一样?

To clarify, would the above piece of code be the same as the below in all respects. 为了明确起见,以上代码在各个方面是否与以下代码相同。

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

    //some student update logic
}

I think this is a basic question,but have seen other questions but couldn't get it clarified. 我认为这是一个基本问题,但已经看过其他问题,但无法澄清。 Thanks. 谢谢。

The short answer: Both will work 简短的答案:两者都会起作用

The long answer: 长答案:

There are a lot of details when it comes to @Transactional and transaction propagation. 关于@Transactional和事务传播,有很多细节。 Here is some info about the simplest scenario that most developer use. 以下是有关大多数开发人员使用的最简单方案的一些信息。

When a Component/Service/Controller has @Transactional Spring will wrap it in a proxy (think decorator pattern), which will create thread local state, to house transaction information and link it to the @PersistenceContext EntityManagers . 当组件/服务/控制器具有@Transactional Spring会将其包装在一个代理(思维装饰器模式)中,该代理将创建线程本地状态,以容纳事务信息并将其链接到@PersistenceContext EntityManagers When the proxy completes the call to your @Transactional method, it will commit the transaction. 当代理完成对@Transactional方法的调用时,它将提交事务。 Since this uses thread local state any @PersistenceContext annotated EntityManager which is used inside your @Transactional method, or any method it invokes, even methods in other beans will share the same transaction and persistence context. 由于此方法使用线程本地状态,因此在@Transactional方法内部使用的任何@PersistenceContext注释的EntityManager或它调用的任何方法,即使其他bean中的方法也将共享相同的事务和持久性上下文。

In order to understand update better lets look at what happens when an entity is loaded in JPA. 为了更好地了解更新,让我们看看在JPA中加载实体时会发生什么。 When you load an entity, the persistence context saves a copy, and when the transaction commits, it run through all managed entities and compare them to the copy from when it was loaded, based on this it figures out which update statements to send to the database. 当您加载实体时,持久性上下文会保存一个副本,并且在事务提交时,它将遍历所有托管实体,并将它们与加载时的副本进行比较,并以此为基础确定要发送到哪个更新语句。数据库。 So when you load an entity and modify it, you don't have to do anything (except let the transaction commit) to update the database. 因此,当您加载实体并对其进行修改时,您无需执行任何操作(除了让事务提交),即可更新数据库。 When you persist a new entity, you add it to the internal collection of managed entities, and if you send the entity to a method that modifies it this will also end up in the database, as long as the modification happens before the transaction commits, and the entity becomes detached. 当您保留一个新实体时,将其添加到托管实体的内部集合中,并且如果将该实体发送给修改它的方法,则只要修改发生在事务提交之前,它也将最终存储在数据库中,并且实体变得分离。

This is only the top of the iceberg, once you start talking about the different propagation types, manually calling flush or queries that trigger pre-query flush, it can get quite complicated. 这只是冰山一角,一旦您开始谈论不同的传播类型,手动调用刷新或触发查询前刷新的查询,就会变得非常复杂。 In my experience JPA is one of the most underestimated java technologies, on the surface it looks so simple, but if you don't understand the fundamentals, you can spend days understanding/debugging the errors you get. 以我的经验,JPA是最被低估的Java技术之一,从表面上看它是如此简单,但是如果您不了解基本原理,则可以花几天的时间来了解/调试所得到的错误。

暂无
暂无

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

相关问题 我们可以传递方法参数的值和注解吗 - Can we pass value and annotation of method parameters 我们应该传递给方法什么来完成它 - What should we have to pass to method to complete it 如果调用在 Spring 中抛出 RuntimeException 的私有方法,@Transactional 方法是否应该回滚? - Should @Transactional method roll back in case of calling a private method which throws RuntimeException in Spring? @Transactional 方法调用另一个没有@Transactional 注释的方法? - @Transactional method calling another method without @Transactional anotation? 弹簧靴。 @Transactional 方法调用 @Transactional(readonly=true) 方法 - Spring Boot. @Transactional method calling a @Transactional(readonly=true) method 我们应该直接在Java中将参数作为变量或作为新对象传递给方法吗 - Should we pass argument to a method as a variable or as a new object directly in java 在 Spring Boot 应用程序的 @Transactional 方法中调用 flush() - Calling flush() in @Transactional method in Spring Boot application 不调用更新方法的事务性保存 - Transactional saves without calling update method 当我们重写一个方法时,我们应该使用方法签名中的所有参数吗? - When we override a method we should use all the parameters that are in the method signature? Context和InitialContext - 我应该在这些对象上调用close()方法吗? - Context and InitialContext - should I be calling the close() method on these objects?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM