我们是否需要在 Spring 中同时使用 @Transactional 和 @Modifying 注解? [英] Do we need both @Transactional and @Modifying annotation in Spring?

查看:49
本文介绍了我们是否需要在 Spring 中同时使用 @Transactional 和 @Modifying 注解?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在努力了解@Transactional 的工作原理.

我在 Service 类的方法上有 @Transactional 注释,在 Repository 类中的方法上有 @Modifying 注释.带有@Transactional注解的方法是否适用于带有@Modifying注解的Repository中的方法?

我的理解:

<块引用>

@Transactional 使用 @Transactional( readOnly= true ) 没有数据写入数据库,而使用 @Transactional,数据写入数据库.

修改查询

<块引用>

  1. 修改方法签名只能返回voidIntegerint
  2. 更新查询必须是事务性的,用 @Transactional
  3. 标记
  4. Spring Data 将丢弃 EntityManager 中所有未刷新的更改,使用 @Modifying(clearAutomatically=false)
  5. >

正如第二点所说@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();}

我的问题是:

  1. 为什么我们在服务类中需要 @Transactional 当我们在存储库 @Repository 级别拥有它并且我有 @Modifying方法哪个修改实体并将其写入数据库(仅因为我在类级别有 @Transactional(readOnly = true))?
  2. 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

  1. Modifying method signature can only return void, Integer or int
  2. Updating queries MUST be transactional, mark with @Transactional
  3. 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:

  1. 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) ?
  2. 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屋!

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