Spring/스프링 데이터 JPA
[스프링 데이터 JPA] 스프링 데이터 JPA 10. 트랜잭션
주멘이
2021. 1. 17. 13:21
스프링 데이터 JPA가 제공하는 Repository의 모든 메서드에는 기본적으로 @Transaction이 적용되어 있습니다.
스프링 프레임워크가 제공하는 트랜잭션 기능과 거의 흡사하여 JPA 특화라고 보기는 어렵다
스프링 @Transactional
Transactional (Spring Framework 5.3.3 API)
Defines zero (0) or more exception names (for exceptions which must be a subclass of Throwable), indicating which exception types must cause a transaction rollback. This can be a substring of a fully qualified class name, with no wildcard support at presen
docs.spring.io
- 클래스, 인터페이스, 메소드에 사용할 수 있으며, 메서드에 가장 가까운 애노테이션이 우선순위가 높다
JPA 구현체로 Hibernate를 사용할 때 트랜잭션을 readOnly를 사용하면 좋은 점
- Flush 모드를 NEVER로 설정하여, Dirty checking(상태 변화 감지)을 하지 않도록 한다.
- 데이터 변경이 일어나지 않기에 DB Sync를 하지 않는다.
- 데이터를 많이 가져오는 경우에 Dirty checking을 끄면 성능 향상
- 트랜잭션 커밋 시점에 Flush 하지 않으므로 이로 인한 Dirty checking 비용이 들지 않고 CPU 자원 절약
@Service에 @Transactional 설정을 통해 하나의 트랜잭션으로 묶을 수 있다.
@Service
class UserManagementImpl implements UserManagement {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
@Autowired
public UserManagementImpl(UserRepository userRepository,
RoleRepository roleRepository) {
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
/* 여러 Repository를 사용하는 곳을 하나의 트랜잭션으로 묶는다 */
@Transactional
public void addRoleToAllUsers(String roleName) {
Role role = roleRepository.findByName(roleName);
for (User user : userRepository.findAll()) {
user.addRole(role);
userRepository.save(user);
}
}