JpaRepository에서 saveAndFlash를 해도 commiit에 의해그쵸?

결론


아니요.

배경.

SpringBoot는 응용 프로그램에 @Transactional를 설치한 방법에서 호출JpaRepositorysaveAndFlush()의 실현을 진행했다.
코드 리뷰를 진행하면서 "saveAndFlush() 변경 안 하나commit?"라는 평을 받았다.flush 안 할 줄 알았는데commit 관련 문서 등을 보고 "JPA 안 해flush"라는 건 아무 것도 명시되지 않아[1]불안해서 동작 확인을 토대로 조사했다.

동작 확인


설치commit의 방법에서 @TransactionalJpaRepository를 호출한 후 비검사 예외가 발생하면 비검사 예외가 발생하기 전에 변경한 것이 굴러갔는지 확인한다.
흔히 볼 수 있는 사용자 추가 용례를 예로 들다.
동작을 확인할 때 사용하는 코드는 모두 아래 창고에 저장됩니다.
https://github.com/yutatanamoto/jpa-flush-rollback-test

주요 애플리케이션 코드 및 프로필


# UserControler.java
 リクエスト(AddUserRequest: firstName と lastName) を受け取ってユーザー追加処理 (userService.add) を呼び出すだけ
@RestController
@RequiredArgsConstructor
class UserControler {
	private final UserService userService;
	
	@RequestMapping("/users", RequestMethod.POST)
	public void save(@RequestBody AddUserRequest request) {
		userService.add(request.getFirstName(), request.getLastName());
	}
}
# AddUserRequest.java
@Value
class AddUserRequest {
	String firstName;
	String lastName;
}
# UserService.java
ユーザー追加処理の実装
ここが動作確認のメインとなる処理
@Service
@RequiredArgsConstructor
class UserService {
	private final UserRepositpry userRepositpry;
	
	@Transactional
	public void add(String firstName, String lastName) {
		User user = new User(firstName, lastName)
		userRepositpry.saveAndFlush(user);
		// ここで非検査例外発生
		throw new RuntimeException();
	}
}
# User.java
@Entity
@Table("users")
public class User {
	@GeneratedValue
	Long id;
	String firstName;
	String lastName;
}
# UserRepositpry.java
public interface UserRepositpry implements JpaRepository<Long, User> {}
# docker-compose.yml
version: "3.8"
services:
  mysql-container:
    container_name: mysql-container
    image: mysql:8.0.22
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "sample"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "password"
    networks:
      - default
    volumes:
      - ./docker/volumes/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/volumes/mysql/initdb.d:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"
# create_tables.sql
CREATE TABLE users
(
    id         BIGINT AUTO_INCREMENT,
    first_name  VARCHAR(100) NOT NULL,
    last_name   VARCHAR(100) NOT NULL,
    PRIMARY KEY (id)
);

절차.

  • DB의 컨테이너를 시작합니다.
  • $ docker compose up -d
    
  • SpringBoot 응용 프로그램을 실행합니다.
    IntelliJ의 시작 버튼이 열립니다.
  • 다음 CURL 명령을 실행하고 saveAndFlush()를 호출합니다.
  • $ curl 
    
  • 마지막으로 다음 명령을 통해 DB의 내용을 확인합니다.
    만약 굴러온다면 DB는 비어 있을 것이다.
  • $ docker mysql-container mysql -uuser -ppassword `select count(*) from users;`
    

    결실


    $ docker mysql-container mysql -uuser -ppassword `select * from users;`
    0
    
    음반이 0건이어서 말려가는 걸 확인했다.
    대단히 기쁘다.

    참고 자료

  • https://www.baeldung.com/spring-data-jpa-save-saveandflush

  • https://stackoverflow.com/questions/14581865/hibernate-flush-and-commit#:~:text=You need to flush in,changes to your persistence layer .
  • 각주
    잘못 봤을지도 몰라...Stackoverflow에는'아니야UserService#add'라고 듬성듬성 적혀 있다.↩︎

    좋은 웹페이지 즐겨찾기