为什么@Transactional自动保存到数据库 [英] Why does @Transactional save automatically to database

查看:499
本文介绍了为什么@Transactional自动保存到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用@Transactional注释的方法.我从数据库中检索一个对象,更改一个字段,然后从该方法返回.不保存我的对象,数据库无论如何都会被更新,这很奇怪.

I have a method annotated with @Transactional. I retrieve an object from my DB, change a field, and then return from the method. Without saving my object, the database gets updated anyway which is strange.

您能告诉我如何避免这种行为吗?

Could you please tell me how to avoid this beahvior?

推荐答案

此行为是事务性的主要目的之一.

This behaviour is one of the main purposes of transactionality.

在事务方法即将返回之前,事务将提交,这意味着对托管实体的所有更改都将刷新到数据库中.

Before the transactional method is about to return, the transaction commits, meaning all changes to the managed entities are flushed to the database.

如果发生错误,则事务将回滚,这意味着不会对数据库提交任何更改.

If an error occurs, the transaction will be rolled back, meaning that no changes will be committed to the database.

当尝试访问延迟加载的属性(可能是来自实体的集合)时,可能会得到LazyInitializationException.从数据库中获取实体时,不会实例化懒惰的属性.

You are probably getting the LazyInitializationException when trying to access a lazily loaded property, probably a collection from an entity. Lazily loded properties do not get instantiated when you fetch an entitiy from DB.

如果您访问事务中的延迟加载属性,则持久性提供程序将创建查询,实例化结果并将其附加到父"实体.

If you access a lazily loaded property in a transaction, the persistence provider will create a query, instantiate the result and attach it to the 'parent' entity.

如果您希望加载惰性属性,并且能够在不将更改持久保存到数据库的情况下更改您的实体,则可以使用用于惰性属性的获取联接来获取实体.

If you want to have the lazy properties loaded AND be able to change your entity without the changes being persisted to the DB, you can fetch the entity with fetch joins for the lazy properties.

em.createQuery("SELECT e FROM MyEntity e JOIN FETCH e.lazyProp");

然后继续使用@orid描述的方法之一.

Then proceed with one of the methods described by @orid.

如果您不使用提取联接,则需要在事务内部访问延迟加载的属性:

If you are not using fetch joins, you will need to access the lazily loaded properties while still inside the transaction:

myEntity.getLazyProp().size();

注意对size()的呼叫.仅仅调用getter还是不够的,因为您将获得一个代理.您需要执行需要该属性中的实际数据的操作.

Note the call to size(). Calling the getter is not enough as you will get a proxy. You need to perform an operation that needs the actual data from the property.

这篇关于为什么@Transactional自动保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆