我们是否需要在 Spring 中同时使用 @Transactional 和 @Modifying 注解? [英] Do we need both @Transactional and @Modifying annotation in Spring?
问题描述
我仍在努力了解@Transactional 的工作原理.
我在 Service 类的方法上有 @Transactional
注释,在 Repository 类中的方法上有 @Modifying
注释.带有@Transactional
注解的方法是否适用于带有@Modifying
注解的Repository中的方法?
我的理解:
<块引用>@Transactional
使用 @Transactional( readOnly= true )
没有数据写入数据库,而使用 @Transactional
,数据写入数据库.
修改查询
<块引用>- 修改方法签名只能返回
void
、Integer
或int
- 更新查询必须是事务性的,用
@Transactional
标记 - Spring Data 将丢弃
EntityManager
中所有未刷新的更改,使用@Modifying(clearAutomatically=false)
>
正如第二点所说@Modifying
查询必须有@Transactional(readOnly=false)
,所以我们可以在@Service
处添加> 级别方法调用或 @Repository
方法级别调用.如果在 @Service
级别添加,它也适用于从 @Service
级别方法调用调用的 @Respository
方法?>
示例:
@Service类 AnimalServiceImpl 实现 AnimalService {@AutowireAnimalRepository AnimalRepository;@覆盖@交易公共无效持久动物(){....AnimalRepository.save();}@覆盖@Transactional(readOnly = true)公共无效 checkIfAnimalPresent() {...AnimalRepository.checkIfPresent();}@覆盖@交易公共无效删除动物(){...AnimalRepository.deleteAnimal();}}
存储库
@Repository@Transactional(只读=真)公共接口 AnimalRepository 扩展 org.springframework.data.repository.Repository {@修改@询问(...)无效保存();@修改@询问(...)int checkIfPresent()@修改@询问(..)int deleteAnimal();}
我的问题是:
- 为什么我们在服务类中需要
@Transactional
当我们在存储库@Repository
级别拥有它并且我有@Modifying
方法哪个修改实体并将其写入数据库(仅因为我在类级别有@Transactional(readOnly = true)
)? - Service 类上的注解
@Transactional
是否传播到@Repository
类?
我希望我在这里的问题和例子很清楚.
@Transactional
的工作原理:
默认情况下,存储库实例上的 CRUD 方法是事务性的.
对于读取操作,事务配置 readOnly
标志设置为 true
.
所有其他人都使用普通的 @Transactional
进行配置,以便应用默认交易配置.
如果您需要为存储库中声明的方法之一调整事务配置,您可以覆盖该方法并添加具有所需属性值的 @Transactional
注释.
另一种改变事务行为的方法是使用(通常)涵盖多个存储库的外观或服务实现.
其目的是为非 CRUD 操作定义事务边界.
如果您使用这种方法,那么存储库中的事务配置将被忽略,因为外部事务(在服务层中定义)配置决定了实际使用的事务.
参考:Spring Data JPA - 参考文档 -5.7.交易性
I am still trying to wrap my head around how @Transactional works.
I have @Transactional
annotation on Service class's method and @Modifying
annotation on the method in the Repository class. Does method with @Transactional
annotation applies to the method in the Repository with annotation @Modifying
?
My understanding:
@Transactional
on a method of a class with@Transactional( readOnly = true )
no data gets written to the database, whereas with@Transactional
, the data gets written to the database.
Modifying Queries
- Modifying method signature can only return
void
,Integer
orint
- Updating queries MUST be transactional, mark with
@Transactional
- Spring Data will drop all non-flushed changes pending in the
EntityManager
, change with@Modifying(clearAutomatically=false)
As the second point says @Modifying
queries must have @Transactional(readOnly=false)
, so we can either add it at @Service
level method call or @Repository
method level call. If added at the @Service
level it applies to the @Respository
method too which is being called from the @Service
level method call?
Example:
@Service
class AnimalServiceImpl implements AnimalService {
@Autowire
AnimalRepository animalRepository;
@Override
@Transactional
public void persistAnimal() {
....
animalRepository.save();
}
@Override
@Transactional(readOnly = true)
public void checkIfAnimalPresent() {
...
animalRepository.checkIfPresent();
}
@Override
@Transactional
public void deleteAnimal() {
...
animalRepository.deleteAnimal();
}
}
Repository
@Repository
@Transactional(readOnly=true)
public interface AnimalRepository extends org.springframework.data.repository.Repository {
@Modifying
@Query(...)
void save();
@Modifying
@Query(...)
int checkIfPresent()
@Modifing
@Query(..)
int deleteAnimal();
}
My question is around:
- Why do we need
@Transactional
in the service class when we have it at the repository@Repository
level and I have@Modifying
on methods which modify the entity and writes it to the database (only because I have@Transactional(readOnly = true)
at the class level) ? - Does the annotation
@Transactional
on the Service class propogate to@Repository
class?
I hope I am very clear with my questions and examples here.
This how @Transactional
works:
By default, CRUD methods on repository instances are transactional.
For read operations, the transaction configuration readOnly
flag is set to true
.
All others are configured with a plain @Transactional
so that default transaction configuration applies.
If you need to tweak transaction configuration for one of the methods declared in a repository you can override that method and add @Transactional
annotation with required attribute values.
Another way to alter transactional behavior is to use a facade or service implementation that (typically) covers more than one repository.
Its purpose is to define transactional boundaries for non-CRUD operations.
If you use this approach, the transaction configuration at the repositories is then neglected, as the outer transaction (defined in the service layer) configuration determines the actual one used.
Reference: Spring Data JPA - Reference Documentation - 5.7. Transactionality
这篇关于我们是否需要在 Spring 中同时使用 @Transactional 和 @Modifying 注解?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!