Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
303 views
in Technique[技术] by (71.8m points)

java - Do we need both @Transactional and @Modifying annotation in Spring?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...