민서네집

Transaction 테스트 본문

Database

Transaction 테스트

브라이언7 2013. 6. 28. 05:39

웹어플리케이션의 Transaction Test 를 해 보고 싶었다.


지금 사용하는 DB는 MySQL 5.6 버전이고, 웹어플리케이션에서는 Spring 3.2.2 버전을 사용 중이다.


MySQL 의 Default Transaction Isolation Level 은 REPEATABLE READ 라서,


Session (Connection?) 이 다르다면 반복적인 읽기 일관성을 위해 한번 select 한 것은 다른 Sesion 에서 Commit 했다고 하더라도 내가 Transaction 을 Commit 이나 Rollback 하지 않는다면 다른 Session 의 변경사항이 반영되지 않는다. 즉, 내가 한번 select 한 결과는 다른 사람이 커밋했더라도 내가 커밋이나 롤백을 하지 않는다면, 다시 select 해도 다른 사람이 변경한 사항을 볼 수 없는 것이다.


웹브라우저에서 창을 2개 열어서 웹어플리케이션의 똑같은 화면에 각각 접속 해 본다.


MySQL 의 Default Transaction Isolation Level 이 REPEATABLE READ 이므로, 

한 곳에서 INSERT 하면, 다른 쪽에서 다시 조회를 해도 볼 수 없어야 한다.


Spring 에서는 Service 의 메서드 단위로 트랜잭션을 커밋하는데, 그렇다면 조회하고 나서 다시 조회하면 변경 사항을 볼 수 있을까? 


처음에 조회할 때는 커밋 전이므로 다른 사람의 변경 사항을 볼 수 없어야 한다.


그리고 이것이 문제가 되는 이유는 INSERT 할때 테이블의 ID를 얻어오기 위해 기존 TABLE 의 ID 값을 MAX() 로 얻어와서 +1 한다면, 여러 클라이언트에서 동시 접속하는 상황이 아니더라도 에러가 날 것이기 때문이다.


그런데, 조회할 때 서로 다른 웹브라우저 창에서 변경한 내용이 바로 반영된다.


웹어플리케이션에서 Transaction 설정이 제대로 잘 되어 있나 확인해 봐야겠다.

- 일단 이럴 가능성이 높은데, 왜냐하면 웹어플리케이션을 디버깅 해볼때 Service 에서 DAO 쪽의 메서드를 하나 호출할 때마다 바로 DB에 반영이 되는 것을 확인했기 때문이다. (MySQL 의 Transaction Isolation Level 을 READ-COMMITTED 로 변경한 상태였다.)

=> ServiceImpl.java 메서드에서 @Transactional 어노테이션을 줘야지 트랜잭션이 적용된다.


그리고, 다른 한 가지 가능성은, 웹 어플리케이션에서 DB Connection 을 가져올 때, 동시에 접속하는 것이 아니라서, A 라는 웹브라우저에서 접속한 Connection 을 B 웹브라우저에서 접속할 때 다시 사용하는 것이 아닐까 하는 의구심이 들었다.


그래서 한번 사용한 DB Connection 을 다시 사용하지 않고, 다른 것으로 바꿔서 사용하는 DB Connection Pool 옵션이 없을까 고민하면서 검색해 봤다.


[참고] http://netholic.tistory.com/116


maxIdle 과 minIdle 설정을 0 으로 설정해서 테스트 해 보면 되지 않을까 하는 생각이 들었다.


그런데, 이럴 가능성은 별로 없을것 같다.


한번 사용한 DB Connection 을 Connection Pool 로 넣을때나 아니면 Connection Pool 에서 Connection 을 가져올 때 한번은 Commit 이나 Rollback 을 하지 않을까?


결국, 웹어플리케이선에서는 조회를 할 때마다 다른 Connection - 커밋이나 롤백이 된 새로운 Connection - 을 사용하게 되므로, REPEATABLE READ 상태라고 하더라도 다시 조회를 하게 되면 변경사항이 바로 반영될 것 같다.


Comments