본문 바로가기

Server Oriented/Spring

스프링 Transaction 트랜잭션

트랜잭션(@Transactional)은 Controller.java 가 아니라,

ServiceImpl.java 에서 기술(inteface 인 Service.java 에서도 기술하지 않음).


/build.gradle JPA 설정과 다를게 없음.

/src/main/resources/application.yml JPA 설정과 다를게 없음.


table1 과 table2 의 관계는 편의상 1:1 로 설정.

table1 의 col11 이 primary key, Object1.java 연계.

table2 의 col21 이 pk,

table2 의 col11 이 table1 의 col11 대응, Object2.java 연계.

이곳에서는, table2.col11 에 foreign key 세팅이 되지 않은 상태로 본다.

 

fk 가 설정되어 있으면 보다 완벽한 DB 가 될 수는 있겠지만,

여러 DB 테이블들을 다뤄야 하는 상황이라면 앞이 깜깜하다.

여기에서는 테이블 2개를 다루고 있지만,

2개 이상의 테이블들에 대한 트랜잭션 처리에도 응용된다.


/src/main/java/도메인/service/Service1Impl.java

 

@Service

@RequiredArgsConstructor

public class Service1Impl implements Service1{

 

  private final Repository1 repository1;

  private final Repository2 repository2;

 

  @Override

  @Transactional // 기술하지 않으면 Repository 별로 commit 진행되어 트랜잭션 성립하지 않음

  public void register(Object1 inObj1, Object2 inObj2) throws Exception{

    // DB 와 연계되지 않는 entity 로 화면 내용을 모두 받아서, repository 에서 사용하는 entity 로 쪼갤 수 있다

 

    Object1 obj1 = new Object1();

    obj1.setCol12(inObj1.getCol12());

    repository1.save(obj1); // DB 저장시 obj1.col11 에 값이 설정되면 작업 성공

 

    Object2 obj2 = new Object2();

    obj2.setCol11(obj1.getCol11());

    obj2.setCol22(inObj2.getCol22());

    repository2.save(obj2); // DB 저장시 obj2.col21 에 값이 설정되면 작업 성공

  }

 

  // update, remove 등에서도 상기 방식처럼 기술

}


/src/main/java/도메인/repository/Repository1.java

 

public interface Repository1 extends JpaRepository<Object1, Long>{

  // 내용 없음

}


/src/main/java/도메인/repository/Repository2.java

 

public interface Repository2 extends JpaRepository<Object2, Long>{

  // 내용 없음

}


/src/main/java/도메인/domain/Object1.java

 

@Entity

@Table(name="table1")

@Getter @Setter @ToString

public class Object1{

 

  @Id

  @SequenceGenerator(name="OBJECT1_SEQUENCE_GEN",

    sequenceName="seq_table1", initialValue=1, allocationSize=1)

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="OBJECT1_SEQUENCE_GEN")

  private Long col11; // table1 pk

 

  private String col12;

 

  @CreationTimestamp // insert sql 문에서만 이용

  private LocalDateTime isrtDate;

  @UpdateTimestamp // update sql 문에서만 이용

  private LocalDateTime updtDate;

}


/src/main/java/도메인/domain/Object2.java

 

@Entity

@Table(name="table2")

@Getter @Setter @ToString

public class Object2{

 

  @Id

  @SequenceGenerator(name="OBJECT2_SEQUENCE_GEN",

    sequenceName="seq_table2", initialValue=1, allocationSize=1)

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="OBJECT2_SEQUENCE_GEN")

  private Long col21; // table2 pk

 

  private String col22;

 

  private Long col11; // table2 의 col11 조인용

 

  @CreationTimestamp // insert sql 문에서만 이용

  private LocalDateTime isrtDate;

  @UpdateTimestamp // update sql 문에서만 이용

  private LocalDateTime updtDate;

 

}