如何在Java中使用固定器理解@transactional?
在有关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。
资源更新:
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,是负责更新实体而不是弹簧的基础JPA提供商(假设是Hibernate)。 Spring只是提供与休眠的集成支持。
要更新从数据库加载的实体,通常需要确保按以下方式进行以下操作。
开始DB事务
使用
EntityManager
加载要更新的实体。据说加载的实体由此EntityManager
管理,以便它可以保持跟踪对其状态进行的所有更改,并将生成必要的更新SQL以自动更新该实体。对实体的状态进行一些更改。您可以通过任何方式来呼叫任何方法,而不仅仅是限制setter
调用它
冲洗
EntityManager
来调用它。然后,它将生成更新SQL并发送到DB。提交数据库事务
还注意以下内容:
@transactional
,这是通过将其注释给方法来执行(1)和(5)的声明性方法。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.
Begin a DB transaction
Use
EntityManager
to load the entity that you want to update.The loaded entity is said to be managed by thisEntityManager
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.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
Flush the
EntityManager
. It will then generate update SQL and send to DB.Commit the DB transaction
Also note the followings:
@Transactional
which is a declarative way to execute (1) and (5) by annotating it to a method.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.春天在引擎盖下使用Hibernate AS ORM。
当您调用
userrepository.findbyid
时,Hibernate Entity Manager在引擎盖下调用,它从数据库中检索实体,同时使此Entity可管理
(您可以单独阅读有关休眠管理实体)。用简单的词,在所谓的
session
中,简单地用简单的词“记住”对该实体的引用。实际上,它“记住”了它从数据库中检索的所有实体(甚至是通过查询的实体列表)(在非常基本的情况下)。当您进行一些方法
@transactional
时,默认情况下,Hibernatesession
是flushed
完成此类方法后。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 thisentity 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 Hibernatesession
isflushed
when such method is finished.session.flush()
is called under the hood.Once
session gets flushed
, Hibernate pushes all changes made to thesemanaged 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
.