개발환경:
- OS: Oracle Solaris 10(개발서버), Windows XP SP3 / Windows7(개발자 PC)
- DBMS: Sybase ASE 15.5
- JVM: Java2SE 1.6.0_21
- WAS: JBoss EAP 4.3 CP08
- FW: Spring 2.5.6 + iBATIS 2.3.4.726
Spring 설정내역:
<bean id="kflowDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/KFlowDS" />
</bean>
<bean id="ctiDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/CtiDS" />
</bean>
<bean id="kflowTxManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
<tx:advice id="kflowTxAdvice" transaction-manager="kflowTxManager">
<tx:attributes>
<tx:method name="register*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
- 다중 DataSource의 사용
문제상황:
1. Sybase에서 select 쿼리 실행후 commit이 발생함.
2. Sybase에서 StoredProcedure 호출 시 "SET CHAINED OFF" 하라며 에러발생.
1번의 경우 DBA 분께서 지적한 건 성능이슈인데 성능이슈를 논의하는 과정에서 Sybase는 CHAINED
MODE[=setAutoCommit(false)]에서 select에서도 Lock(Shared Lock)을 건다고 하더군요. 문제
의 심각성은 이 Lock Time이 언제까지냐인데 http://sona83.tistory.com/9 를 참고하면 조회후 바로
Lock을 해제한다고 나와있습니다.
그런데 이 설명은 UNCHAINED MODE[=setAutoCommit(true)]상황에서라고 DBA는 말하고 있습니다. DBA
가 원하는 근본적인 해결방안은 조회시에 setAutoCommit(true)로 실행해야 한다는 것입니다. 즉, Sybase DB에
서 조회는 트랜잭션이 동작하지 않아야 한다는 것입니다.
구글링을 해봐도 적절한 해결방법을 찾지 못하겠더군요.
2번의 경우 말그대로 CHAINED MODE[=setAutoCommit(false)]에서는 동작하지 않는다는 것입니다.
Sybase DB의 SP는 anymode로 실행하면 CHAINED/UNCHAINED 모두 실행이 가능하며 호출된 SP는
anymode로 선언되어 있다고 하더군요.
질문요약:
1. Sybase에서 select 쿼리 실행후 commit이 발생하지 않도록 할 수 있는가?
2. Sybase에서 StoredProcedure 호출 시 "SET CHAINED OFF" 에러에 대해서 해결방안은 있는가?
환경설정내역을 첨부하지 못해서 죄송합니다.
감사합니다.
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.
제가 테스트하려 했던방법은 NotSupported 를 고려해봤었습니다.
지금시점에서는 트랜잭션을 태우지 않는 방법과 NotSupported가 비슷할 것 같긴한데
예상되는 문제는 트랜잭션내에서 어떤 데이터가 변경된 것을 다시 읽어서 처리해야 할 때 인것 같습니다.
어떤 결과가 나오던 공유하도록 하겠습니다.
다시한번 감사합니다.
물론 서비스 로직을 트랜젝션으로 묶고 read-only로 설정했는데 해당 서비스
에서 실행하는 쿼리가 여러개라면 단일 쿼리마다 자동으로 commit이 되는
unchained 모드가 더 효율적일 수 있습니다. 하지만 non-repeatable reads가
발생하는 문제가 생깁니다.
commit은 db 성능을 높이기 위해 하는 게 아니라 로직에 문제가 안 생기도록
단위 업무(unit of work)에 따라 실행 되어야 한다고 봅니다.
> 2번의 경우 말그대로 CHAINED MODE[=setAutoCommit(false)]에서는 동작하지 않는다는 것입니다.
> Sybase DB의 SP는 anymode로 실행하면 CHAINED/UNCHAINED 모두 실행이 가능하며 호출된 SP는 anymode로 선언되어 있다고 하더군요.
sp가 anymode로 선언되어 있는데도 저런 에러가 나나요? 뭔가 상황에 안 맞는
느낌이 드네요. 직접 콘솔에서 chained 모드와 unchained 모드로 해 놓고 해
당 sp를 실행해보셔야 할 듯 합니다.
Chained Mode에서 select하면 shared lock이 발생된다고 하셨는데, 이건 chained , unchained
하고는 상관없는 사항입니다.
chained, unchained는 단순히 transaction을 명시적으로 사용하질의 여부입니다.
(DBMS 기본 세팅값을 확인하고 싶네요... select @@tranchained --결과 값이 0이면 unchained
mode이고, 1이면 chained 모드입니다.)
만약 spring과 무관하다면 아마 DB환경값중에 default isolation값이 2이상으로 설정되어 있을 겁니다. 확인방법
은 (select @@isolation)하시면 됩니다.
참고로 isolation은 내 트랙잭션을 다른 트랜젹션 동작으로부터 보호하기 위한 걸로 이해하시면 됩니다.
이 경우에는 내가 select한 내용은 모두 shared lock이 걸립니다. 재 조회시에 동일 값을 보장하기 위한 방법이지
요.
말씀처럼 chained모드와 무관하게 isolation(>=2)값에서는 "트랜잭션 내부"에서의 select는 lock이 걸리며
트랜잭션이 종료되야 lock이 해제됩니다.
일단...저라면,
개발 환경 세팅중에 datasource부분에서 isolation level을 setting 할 수 있는데, 그값을 확인해보구
요..
DBMS의 default isolation level을 확인하고.
spring 환경에서...디버깅모드에서..(select @@isolation) 값을 확인하겠습니다.
hibernate사용시에 몇가지 이슈가 있었거든요...결국은 모두 해결했는데, 기억이 잘나질 않네요..ㅜㅜ
참고로...덧붙이자면,,
Sybase의 범위를 벗어나서 트랜잭션모드는 unchained, isolation은 read committed( = '1' )값
으로 세팅하고,
개발시에 명시적으로 begin tran, commit, rollback statement를 사용하는게 100배 낫습니다. ㅡ
ㅡ;
제가 회의가 있어서...궁금하신 사항은...메일로 주세요...
> 의 심각성은 이 Lock Time이 언제까지냐인데http://sona83.tistory.com/9를 참고하면 조회후 바로
일단 정상혁님이 말씀하셨던 방법으로 하니 select 다음에 commit 이 실행되지 않더군요.
또한 제가 원래 생각했던 방법인
<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />
로 실행해도 동일한 결과를 얻을 수 있었습니다.
동일한 결과가 도출이 됨으로써 NOT_SUPPORTED를 사용하는 것으로 결정했습니다.
명시적인 트랜잭션 설정으로 개발자들에게 전파하는게 유리할 것 같아서 입니다.
2번째 이슈는 다른 SP는 정상동작하는 것으로 확인이 되었으며
해당 SP에 문제가 있었던 것으로 잠정 결정을 내렸습니다.
보다 자세한 원인은 레거시쪽의 분석이 필요해서 원인이 밝혀지면 공유하도록 하겠습니다.
해결방법의 실마리를 KSUG 모든 분들에게 다시한번 감사드립니다.
프로젝트 진행시 발생하는 개발이슈는 지속적으로 공유하도록 하겠습니다.
감사합니다.
On 2월12일, 오전9시53분, Sanghyuk Jung <bene...@gmail.com> wrote:
> 안녕하세요,
>
> DBMS와 DataSource 구현체에 따라서 달라질 수 있는 동작이라서, 어려운 문제네요 ^^;
>
> 다른 DBMS에서 였지만 제 경험을 공유해드리면,
> DBA가 큐브리드 DB에서는 select후에 rollback을 시키는 것이 성능에 좋다고 어플리케이션에서 그렇게 할 것을 요구했었습니다.
> 어떻게 해야하나 고민을 했는데,select쿼리만 있는 메소드들은 아예 트랜잭션 선언을 하지 않고 있으니, DBA가 원하는대로
> rollback되는 것으로 쿼리가 들어오고 있다고 하더군요.
>
> 즉 위의 예제같으면
> <tx:method name="*" read-only="true" />
>
> 부분을 아예 지운다면, 당시에 제가 썼던 선언와 유사해 질 것 같습니다.
>
> 아마 환경과 구현체가 다 달라서 다르게 동작할 가능성이 크지만, 참고삼아서 말씀드렸습니다.
>
> 2011년 2월 11일 오후 1:55, 임병인(포데브) <brianlim.next...@gmail.com>님의 말:
On 2월14일, 오후6시41분, Sungchul Park <gyu...@gmail.com> wrote:
> > 문제상황:
> > 1. Sybase에서 select 쿼리 실행후 commit이 발생함.
> > 2. Sybase에서 StoredProcedure 호출 시 "SET CHAINED OFF" 하라며 에러발생.
>
> > 1번의 경우 DBA 분께서 지적한 건 성능이슈인데 성능이슈를 논의하는 과정에서 Sybase는 CHAINED
> > MODE[=setAutoCommit(false)]에서 select에서도 Lock(Shared Lock)을 건다고 하더군요. 문제
> > 의 심각성은 이 Lock Time이 언제까지냐인데http://sona83.tistory.com/9를 참고하면 조회후 바로 Lock을 해제한다고 나와있습니다.
> > 그런데 이 설명은 UNCHAINED MODE[=setAutoCommit(true)]상황에서라고 DBA는 말하고 있습니다. DBA가 원하는 근본적인 해결방안은 조회시에 setAutoCommit(true)로 실행해야 한다는 것입니다. 즉, Sybase DB에서 조회는 트랜잭션이 동작하지 않아야 한다는 것입니다.
> > 구글링을 해봐도 적절한 해결방법을 찾지 못하겠더군요.
>
> 뭔가 오해가 있다고 생각하는데요. UNCHAINED 모드라고 해서 트랜젝션이 작동
> 하지 않는 건 아닌 걸로 압니다. 트랜젝션이 작동 안 한다면 말이 안 되죠.
> UNCHAINED 모드와 CHAINED 모드는 명시적으로 트랜젝션을 거느냐 방법과 암묵
> 적으로 트랜젝션이 걸리는 범위의 차이일 뿐인 걸로 알고 있습니다. 이 경우
> shaed lock은 어느 모드에서나 걸리며 commit 명령을 보내 lock을 푸느냐 자
> 동으로 풀리느냐 차이인거죠.
>
> 물론 서비스 로직을 트랜젝션으로 묶고 read-only로 설정했는데 해당 서비스
> 에서 실행하는 쿼리가 여러개라면 단일 쿼리마다 자동으로 commit이 되는
> unchained 모드가 더 효율적일 수 있습니다. 하지만 non-repeatable reads가
> 발생하는 문제가 생깁니다.
>
> commit은 db 성능을 높이기 위해 하는 게 아니라 로직에 문제가 안 생기도록
> 단위 업무(unit of work)에 따라 실행 되어야 한다고 봅니다.
일단 DBMS 설정은 isolation level은 1(READ_COMMITEED)이고 UNCHAINED 모드 였습니다.
그리고 JBoss에서 별도의 설정을 하지 않았으므로 isolation level은 DBMS를 따를 것이고 DataSource를
사용하므로
컨넥션에 대해 setAutoCommit(false)가 자동 실행됩니다.
위의 상황에서 Sungchul Park 님이 지적하신 문제에 대해 DBA분에게 큰 문제가 없을 것이라 했는데 select 쿼리시
에
commit이 실행되는 것은 반드시 제거해야 하며 고객사 또한 기존 운영에서도 발생하지 않는 문제이니 해결해야 한다는
강력한 의지가 있었습니다.
좋은 의견 감사하며 앞으로 프로젝트를 진행하면서 non-repeatable read의 문제 상황이 발생할 경우 좋은 지침이 될
것 같습니다.
> > 2번의 경우 말그대로 CHAINED MODE[=setAutoCommit(false)]에서는 동작하지 않는다는 것입니다.
> > Sybase DB의 SP는 anymode로 실행하면 CHAINED/UNCHAINED 모두 실행이 가능하며 호출된 SP는 anymode로 선언되어 있다고 하더군요.
>
> sp가 anymode로 선언되어 있는데도 저런 에러가 나나요? 뭔가 상황에 안 맞는
> 느낌이 드네요. 직접 콘솔에서 chained 모드와 unchained 모드로 해 놓고 해
> 당 sp를 실행해보셔야 할 듯 합니다.
anymode로 되어 있는 다른 SP를 실행해보니 정상동작하는 것을 확인했습니다.
결론은 에러가 발생한 SP내부의 문제로 보여지며 원인이 밝혀지면 공유하도록 하겠습니다.
감사합니다. 좋은 하루 되십시요. ^^;
※ 그러므로 이문제는 정상혁님이 제시한 것처럼 선언자체를 안하는 방법밖에는 없어보입니다.