如何在Java中使用固定器理解@transactional?

发布于 2025-01-22 10:11:59 字数 1494 浏览 5 评论 0原文

在有关Java Spring的教程之后,我试图了解 @Transactional如何与Setters一起工作,从其他问题/来源中,我找不到对此的友好解释。

假设我有一个带有getters和setter的用户实体:

@Entity
public class User {
    // Id set up
    private Long id;
    private String name;
    private String email;
    private String password;

    // Other constructors, setters and getters

    public void setName(String name) {
        this.name = name;
    }
}

在用户服务中,我有一个getUsername方法:

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void getUserName(Long id) {
        User user = userRepository.findById(id).orElseThrow();

        user.setName("new user name"); // Why will this update db?     
    }
}

使用@transactional注释,setter函数确实会更新DB,这是更新数据的弹簧方式吗?有人可以在外行术语中解释,交易方式如何与引擎盖下的固定器一起工作?

编辑: 没有@transactional,setter函数不会更新db,而是在 为了突变DB,必须调用userrepository.save(用户)。从视频,讲师简单地说,交易型简单地说,交易者将为我们处理JPQL,并使用Setters,并使用Setters以及它更新DB。

资源更新:

spring noreferrer“> spring Transaction” a>,希望这有帮助。

Following tutorial on Java Spring, I'm trying to understand how does @Transactional work with setters, and from other question/sources, I can't find a beginner-friendly explanation for it.

Let's say I have a user entity with getters and setters:

@Entity
public class User {
    // Id set up
    private Long id;
    private String name;
    private String email;
    private String password;

    // Other constructors, setters and getters

    public void setName(String name) {
        this.name = name;
    }
}

And in the UserService I have a getUserName method:

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void getUserName(Long id) {
        User user = userRepository.findById(id).orElseThrow();

        user.setName("new user name"); // Why will this update db?     
    }
}

With @Transactional annotated, the setter function does update db, is this the spring way of updating data? Can someone help explain in layman term, how the Transactional work with setters under the hood?

Edit:
Without @Transactional, setter function won't update db, but in
order to mutate db, will have to call userRepository.save(user). And from the video, the instructor simply says the Transactional will handle jpql for us, and use setters along with it to update db.

Resource update:

Spring Transaction Management: @Transactional In-Depth, hope this is helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

国粹 2025-01-29 10:11:59

首先,是负责更新实体而不是弹簧的基础JPA提供商(假设是Hibernate)。 Spring只是提供与休眠的集成支持。

要更新从数据库加载的实体,通常需要确保按以下方式进行以下操作。

  1. 开始DB事务

  2. 使用EntityManager加载要更新的实体。据说加载的实体由此EntityManager管理,以便它可以保持跟踪对其状态进行的所有更改,并将生成必要的更新SQL以自动更新该实体。

  3. 对实体的状态进行一些更改。您可以通过任何方式来呼叫任何方法,而不仅仅是限制setter

    调用它

  4. 冲洗EntityManager来调用它。然后,它将生成更新SQL并发送到DB。

  5. 提交数据库事务

还注意以下内容:

  • Spring提供@transactional,这是通过将其注释给方法来执行(1)和(5)的声明性方法。
  • 默认情况下,Hibernate将在执行(5)之前自动致电(4),因此您无需明确调用(4)。
  • Spring Data JPA存储库内部使用EntityManager来加载用户。因此,用户将从存储库返回,该EntityManager将管理。

因此,简而言之,@transactional对于更新实体是必要的。并且更新实体与Setter无关,因为它最终是否在实体上有状态更改,并且您可以在不使用setter的情况下进行此操作。

Firstly, it is the underlying JPA provider (assume it is Hibernate) to be responsible for updating the entity but not Spring. Spring just provides the integration support with Hibernate.

To update an entity loaded from the DB , generally you need to make sure the following happens in order.

  1. Begin a DB transaction

  2. Use EntityManager to load the entity that you want to update.The loaded entity is said to be managed by this EntityManager such that it will keep track all the changes made on its state and will generate the necessary update SQL to update this entity in (4) automatically.

  3. Make some changes to the entity 's state. You can do it through any means such as calling any methods on it , not just restricting to calling it by setter

  4. Flush the EntityManager. It will then generate update SQL and send to DB.

  5. Commit the DB transaction

Also note the followings:

  • Spring provides @Transactional which is a declarative way to execute (1) and (5) by annotating it to a method.
  • By default , Hibernate will call (4) automatically before executing (5) such that you do not need to call (4) explicitly.
  • Spring Data JPA repository internally use EntityManager to load the user. So the user return from the repository will be managed by this EntityManager.

So in short , @Transactional is necessary to update the entity. And updating the entity is nothing to do with setter as it just care if there are state changes on the entity in the end , and you can do it without using setter.

鹤仙姿 2025-01-29 10:11:59

春天在引擎盖下使用Hibernate AS ORM。
当您调用userrepository.findbyid时,Hibernate Entity Manager在引擎盖下调用,它从数据库中检索实体,同时使此Entity可管理(您可以单独阅读有关休眠管理实体)。
用简单的词,在所谓的session中,简单地用简单的词“记住”对该实体的引用。实际上,它“记住”了它从数据库中检索的所有实体(甚至是通过查询的实体列表)(在非常基本的情况下)。

当您进行一些方法@transactional时,默认情况下,Hibernate sessionflushed完成此类方法后。 session.flush()在引擎盖下调用。

一旦会话被冲洗,Hibernate便将对这些托管实体进行的所有更改都推回了数据库。

这就是为什么您的更改到达数据库的原因,一旦方法完成,没有任何其他呼叫。

要深入研究主题,您可以阅读有关Hibernate托管实体的更多信息session flush模式repository.save(),repository.saveandflush()数据

Spring uses Hibernate as ORM under the hood.
When you call userRepository.findById, Hibernate entity manager is called under the hood, it retrieves entity from database and at the same time makes this entity manageable (you can read separately about Hibernate managed entities).
What it means, in a simple words, the Hibernate 'remembers' the reference to this entity in its internal structures, in the so-called session. It, actually, 'remembers' all entities which it retrieves from database (even the list of entities obtained by queries) during single transaction (in the very basic case).

When you make some method @Transactional, by default Hibernate session is flushed when such method is finished. session.flush() is called under the hood.

Once session gets flushed, Hibernate pushes all changes made to these managed entities back into the database.

That is why your changes got to the database, once method was finished, without any additional calls.

To dig deeper into the topic, you can read more about Hibernate managed entities , session flush mode, repository.save(), repository.saveAndFlush() in Spring Data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文