기존에 JPA를 사용할 때 @Transactional을 사용해서
자동으로 커밋, 롤백을 처리하게 사용했다
그렇게 사용하는것이 스프링부트에서 권장하는 방법이지만
JDBC에서 직접 커넥션풀을 열고 닫고 또는 커밋 롤백 하듯이
JPA에서도 가능하다고 하기에 해보고자 한다
1. 개발 환경
- Java 17
- SpringBoot 2.7.14
- JPA
- Postgresql
- Maven
- IntelliJ
dependency
- spring-boot-starter-web
- spring-boot-starter-data-jpa
- spring-boot-devtools
- postgresql
- lombok
2. Properties
# DataSource configuration
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
## Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.connection.autocommit=false
3. Controller
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MemberController {
private final MemberService memberService;
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
@PostMapping("/aaa")
public String createMember(@RequestBody Member newMember) {
String createMember = memberService.createMember(newMember);
System.out.println(createMember);
return createMember;
}
@PostMapping("/ttt")
public String createMemberTransaction(@RequestBody Member newMember) {
String createMemberTransaction = memberService.createMemberTransaction(newMember);
System.out.println(createMemberTransaction);
return createMemberTransaction;
}
}
4. Service
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MemberService {
// 엔티티 매니저 팩토리 객체 생성
private final EntityManagerFactory emf;
// 멤버 레포지토리 객체 생성
private final MemberRepository memberRepository;
public String createMember(Member newMember) {
// 엔티티 매니저 객체 생성
EntityManager em = emf.createEntityManager();
// 트랜잭션 사용을 위한 객체 생성
EntityTransaction transaction = em.getTransaction();
try {
// 트랜잭션 시작
transaction.begin();
// 엔티티 객체의 상태 변경
em.persist(newMember);
// 트랜잭션 커밋
transaction.commit();
return "Commit successful. New member created.";
} catch (Exception e) {
// 예외 발생 시 롤백
transaction.rollback();
return "Commit failed. Transaction rolled back.";
} finally {
// 엔티티 매니저 종료
em.close();
}
}
@Transactional(rollbackOn = Exception.class)
public String createMemberTransaction(Member newMember) {
// 멤버 중복 아이디 찾기
Member existingMember = memberRepository.findById(newMember.getId()).orElse(null);
// 중복 값 예외 처리
if (existingMember != null) {
throw new IllegalArgumentException("ID already exists: " + newMember.getId());
}
// 엔티티 객체의 상태 변경
memberRepository.save(newMember);
return "Commit successful. New member created.";
}
}
5. Member
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "member")
public class Member {
@Id
@Column(name="MEMBER_ID" ,nullable = false)
private String id;
@Column(name="MEMBER_NAME" ,nullable = false)
private String memberName;
}
6. Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MemberRepository extends JpaRepository<Member, String> {
}
'DataBase' 카테고리의 다른 글
| [DataBase] 식별 관계와 비식별 관계 (0) | 2023.09.18 |
|---|---|
| [DataBase] TimescaleDB 특징, 설치 방법 및 테스트 (0) | 2023.08.04 |
| [DataBase] Elasticsearch bulk 구현 (0) | 2023.07.21 |
| [DataBase] Elasticsearch 로컬 인증서 등록 방법 (keytool) (0) | 2023.07.14 |
| [DataBase] Elasticsearch + kibana + docker-compose (HTTPS 방식) (0) | 2023.07.06 |