Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Transaction Manager - 1 본문

JPA/영속성

Transaction Manager - 1

Seung__ 2021. 7. 4. 15:03

 

 1. Transaction이란?


Data Base에서 다루는 개념. DB명령어들의 논리적인 묶음이다.

 

Transaction의 성질 : ACID

  A : atomatic(원자성),  부분적의 성공을 허용하지 않는다. 

      중간 단계까지 실행되고 실패하는 일이 없도록 하는 것

 

  C : consistance(일관성), 고립된 트랜잭션의 수행이 데이터베이스의 일관성을 보존해야 한다.

  즉, 성공적으로 수행된 트랜잭션은 정당한 데이터들만을 데이터베이스에 반영해야 한다. 

  예를들어 예금 이체의 같은 경우 두 계좌의 금액의 합은 이체 전후 동일해야 한다.

 

  I : isolation(독립성), transaction 내 data 조작에 대해서는 다른 transaction으로부터 독립적이다.

     트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것

 

  D : durability(지속성), 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다.

   (출처 :  https://ko.wikipedia.org/wiki/ACID)

 

 

Transaction, @Transactional

1. Transaction 데이터 베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위. 예를들어 A가 B에게 100만원을 송금한다 할 때. 논리적인 기능은 송금. 송금을 위한 작업은 "A인

bsh-developer.tistory.com

 

 

2. Transaction Test


@Transactional에 의한 DB반영 시점을 test 해보자!

 

1) BookService class와 Test를 만들어 주자.

<BookService>

@Service
@RequiredArgsConstructor
public class BookService {

   // @Autowired //요즘에는 Autowired보다는...생성자 주입@RequiredArgsConstructor, final이기 때문에 생성자 반드시 필요.
    private final BookRepository bookRepository;

   // @Autowired
    private final AuthorRepository authorRepository;

    public void putBookAndAuthor(){

        Book book = new Book();
        book.setName("JPA 시작작");
        bookRepository.save(book); //DB insert

        Author author = new Author();
        author.setName("hyun");
        authorRepository.save(author); // DB insert
        
    }
}

<Test>

@SpringBootTest
class BookServiceTest {

    @Autowired
    private BookService bookService;
    @Autowired
    private BookRepository bookRepository;
    @Autowired
    private AuthorRepository authorRepository;

    @Test
    void transactionTest(){

        bookService.putBookAndAuthor();

        System.out.println("books : " + bookRepository.findAll());
        System.out.println("Authors : " + authorRepository.findAll());
    }
}

 

2) DB 준비

먼저 MySQL을 준비하자!

 

MySQl 추가 및 설정.

0. MySQL설치 MySQL 설치 1. 접속 : www.mysql.com/ 2. downloads 클릭 3. 하단 GPL(General Public License) download 클릭 3. installer For Windows선택 4. 용량 큰놈 선택 5. 로그인 제껴버리기 6. 다운로드..

bsh-developer.tistory.com

 

MySQL 준비가 끝나면 콘솔창을 열어서 순서대로 실행해주자.

   -  create database book_manager : book_manager DB 생성!

   -  use book_manager : book_manager DB 사용!

   - show tables를 실행해서 어떤 table이 있는지 확인해보자.

      아무 table도 없다? 

아직은 아무 table도 없다.

     

       왜 없냐면  ddl-auto를 create-drop으로 설정했기 때문이다.(ddl-auto는 아래 글 참고)

       따라서 test 종료 후 data가 삭제되어 table이 남아있지 않다.

 

 

JPA/Hibernate 초기화(ddl-auto, initialization-mode 등)

0. Hibernate JPA의 구현체로 jpa를 한번 감싸서 사용하기 쉽게 해줌 JPA 소개 1. ORM(Object Relational Mapping)  객체와 관계형 Database를 자동으로 mapping시켜주는 것을 말한다.  객체지향 프로그래밍의..

bsh-developer.tistory.com

   

 

  - 그러면 Transacion이 끝나지 않게 중간에 break point를 걸어보자. 

   해당 시점은 put method가 종료되어 book, author가 생성되고 각각 save된 이후이다.

 

  - DB 콘솔창을 열어서 아래 명령어를 실행해주자.

     show tables : 아까와는 다르게 table이 생성되었다.

 select * from user : 예전에 미리 입력해둔 user정보가 불어와졌다.

 

 

 

3. @Transactional 적용


이 상태에서 @Transactional을 붙이면???? 작성한 putBookAndAuthor method에 붙여보자.

@Service
@RequiredArgsConstructor
public class BookService {

   // @Autowired //요즘에는 Autowired보다는...생성자 주입@RequiredArgsConstructor, final이기 때문에 생성자 반드시 필요.
    private final BookRepository bookRepository;

   // @Autowired
    private final AuthorRepository authorRepository;

    @Transactional
    public void putBookAndAuthor(){

        Book book = new Book();
        book.setName("JPA 시작작");
        bookRepository.save(book); //DB insert

        Author author = new Author();
        author.setName("hyun");
        authorRepository.save(author); // DB insert

    }
}

 

break point는 1)book save이후 2) autho save이후 이다.

 

 

 

book을 save한 후에 DB 콘솔에서 select * from book을 실행해보자

 

예상대로 아무것도 없다. Transaction이 아직 끝나지 않아 영속성 context에만 존재하고 DB에 반영되지 않은 상태이다.

 

 

Author까지 save가 끝나고 Transaction이 종료된 시점에서 다시 book과 author을 불러와보자.

 

콘솔 창을 보면 실제로 insert query가 실행된 것을 확인할 수 있다.

Hibernate: 
    insert 
    into
        book
        (created_at, updated_at, author_id, category, name, publisher_id) 
    values
        (?, ?, ?, ?, ?, ?)
2021-07-04 14:42:33.800  WARN 11400 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=4m44s698ms612µs500ns).
Hibernate: 
    insert 
    into
        author
        (created_at, updated_at, country, name) 
    values
        (?, ?, ?, ?)

 

 

4. 결론


짠 DB에 반영이 된 것을 모두 확인했다.

 

여러 쿼리는 하나의 transaction으로 묶여서 동작하게 된다.

 

모든 쿼리가 문제없이 실행된 이후에 DB반영을 위한 commit을 한다.

 

각각의 save 실행된 시점에는 commit하지 않다가 transaction이 완료된 시점에commit ->  DB 반영이 이루어진다.

 

 - method 시작= transaction 시작

 - method 종료 = trasaction 종료

 

 

5. GitHub

 

bsh6463/BookManager

Contribute to bsh6463/BookManager development by creating an account on GitHub.

github.com

 

'JPA > 영속성' 카테고리의 다른 글

Transaction Manager-3 : Isolation  (0) 2021.07.04
Transaction Manager - 2  (0) 2021.07.04
Entity 생애 주기  (0) 2021.07.04
Entity Cache  (0) 2021.07.02
영속성 컨텍스트  (0) 2021.07.01
Comments