본문 바로가기

Java

ibatis와 dbcp (Select문에 대한 rollback 실행)

http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=40288


처음에는 어느 블로그에서 글을 보고

그걸 바탕으로 조사를 했었는데, 위 기고문의 내용을 보니...

처음 참고하였던 그 블로그와는 내용이 조금 다른(?.. 결과적으로는 같지만.. 과정 설명이 좀 다른.. )..

좀 미묘하게 차이가 나는 부분이 있어서 위 글을 보고 소스를 열어서 참고해보았다.


일단.... ibatis의 아래 설정에 의해서..

<transactionManager type=”JDBC”>

....

</transactionManager>


ibatis에서 JDBCTransaction이 사용되고.. 거기서 아래와 같이 connection.setAutoCommit(false)가 실행됨..

if(conn.getAutoCommit()) {

  conn.setAutoCommit(false);

}



ibatis에서 commit을 실행하는 조건은

if (session.isCommitRequired() || forceCommit) {

trans.commit();

session.setCommitRequired(false);

}

임...


session.isCommitRequired는 sqlMapClient에서 excuteUpdate등을 실행 할 때 true로 셋팅되며 

forceCommit은 ibatis설정에서 commitRequired=true를 설정하면 true가 된다.

디폴트 설정에서는 forceCommit은 항상 false이기 때문에, JDBC Connection의 autoCommit이 항상 true라고 하더라도..

맨 위에서 false가 되어버리지만.. update, delete에서는 commitRequired에 의해서 commit이 이루어진다.


반대로 ibatis의 transaction설정에서 commitRequired=true라면..select문에 대해서도 무조건 commit이 실행됨.


그러면...디폴트 설정에서  select 실행시에는 autocommit=false인 상태로 connection이 반환되는건가?


아래의 DBCP의 PoolabledConnectionFactory를 보면 connection을 반환할때 아래의 문장이 실행되는데

if(!conn.getAutoCommit() && !conn.isReadOnly()) {

conn.rollback();

}

conn.clearWarnings();

if(!conn.getAutoCommit()) {

conn.setAutoCommit(true);

}

autoCommit은 false인 상태이므로...

rollback은 무조건 한번씩 실행되는 것 같다.. select이건 뭐건 실행되기 때문에...
마소 기고문에서 이야기하는 공롤백이 여기서 일어남... 근데 update, delete를 실행하여 이미 commit이 된 상태에서도..
롤백이 한번씩 더 실행될 것 같음..

혹시나해서 c3p0로 connection pool을 변경해서 테스트해보았는데 select시에 rollback은 여전히 발생한다.

그런데 ibatis + weblogic에서는 롤백이 발생하지 않는다고 함.. connection pool의 차이인가...
mybatis는 저 부분에 대한 처리를 로직적으로 한 것 같음. (JDBCTransaction.java에 resetAutoCommit 메서드..)

그렇다면 드는 의문이..
ibatis에서... 왜 무조건 autocommit=false를 찍고 들어가는걸까... 자기가 트랜잭션 관리를
하기 위해서인가... 그걸 좀 찾아봐야겠다..