티스토리 뷰

Development/MSSQL

트랜잭션

오틸라 2008. 5. 27. 20:04
반응형
데이터베이스 작업의 단위를 말합니다.
이는 작업의 일관성과 관계가 있습니다.
트랜잭션의 처리과정을 한마디로 표현하자면 All or Nothing 이라고 하지요.
다음은 BOL에서 말하는 트랜잭션에 대한 정의입니다.

트랜잭션은 하나의 논리적 작업 단위로 수행되는 일련의 작업입니다.
작업의 논리적 단위는 ACID(원자성, 일관성, 격리성 및 영속성) 속성이라고 하는 네 가지 속성을 통해
트랜잭션으로서의 자격을 부여합니다.

원자성
트랜잭션은 더 이상 분류할 수 없는 작업 단위여야 하며 모든 데이터 수정 작업이 수행되거나 하나도
수행되지 말아야 합니다.

일관성
완료된 트랜잭션의 모든 데이터는 일관적이어야 합니다.
관계형 데이터베이스에서는 트랜잭션 수정에 모든 규칙을 적용하여 모든 데이터 무결성을 유지해야 합니다.
트랜잭션 마지막에는 B-tree 인덱스 또는 이중 연결 목록 등 모든 내부적 데이터 구조를 반드시 수정해야 합니다.

격리성
동시 트랜잭션에 의한 수정은 다른 동시 트랜잭션에 의한 수정과 격리되어야 합니다.
트랜잭션에서 다른 동시 트랜잭션이 수정하기 전 상태의 데이터를 보거나,
두 번째 트랜잭션이 완료된 후의 데이터를 볼 수는 있지만 중간 상태는 볼 수 없습니다.
결과적으로 시작 데이터를 다시 로드하고 일련의 트랜잭션을 재생하여 원래 트랜잭션이 수행된 후의 상태로
데이터를 되돌릴 수 있는데 이를 순차성이라고 합니다.

영속성
트랜잭션이 완료되고 나면 그 영향이 영구적으로 시스템에 적용됩니다.
수정은 시스템에 오류가 발생한 경우에도 지속됩니다.

너무 어려워하지 마시고 예를 들도록 하지요.
어느 책에서나 트랜잭션하면 튀어나오는 예제... 바로 은행입니다.

데이터베이스는 모든 작업을 메모리로 불러와서 작업을 합니다.
메로리상에서 처리되는 것이 하드디스크에서 처리되는 것에 비해 엄청나게 빠르기 때문입니다.
그리고 즉시 실제데이터에 기록되는 것이 아니라 로그에 기록이 된후 나중에 실제 데이터에 기록됩니다.
문제는 여기서 시작됩니다.
여러분이 은행에 100원이 들어있는데 어느날 큰맘을 먹고 10000원을 입금하였습니다.
그럼 update가 일어나겠지요?
근데 미처 데이터가 저장되기전에 서버가 갑자기 다운이 되버리면?
다시 서버를 작동시키게 되면 은행은 낼름하고 10000원을 먹었는데 계좌에는 100원밖에 없는 불상사가 생기는
것입니다.
이런 경우 로그를 기반으로 하여 이 작업을 되살리거나 아니면 모두 없었던 일로 합니다.
이것이 All or Nothing의 개념입니다.

MS-SQL은 기본적으로 Auto Commit입니다.
이말은 여러분이 데이터를 업데이트 하거나 지울시 사용자의 지시없이 자동으로 허락한다는 말입니다.
다음을 보시지요...

  

  begin tran을 사용하여 명시적으로 트랜잭션을 선언하였습니다.
그리고 Update를 사용하여 presidant를 president로 바꾸었습니다.
만약 이 작업이 잘못된거라서 취소하고 싶다면?

  
  rollback tran을 선언하여 이 트랜잭션을 취소시켰습니다.
select 하여 값을 보니 원래대로 돌아왔네요...
아까의 Update가 바로된것이라면 rollback tran이 아닌 commit tran을 하여 이 트랜잭션을 OK하고 종료합니다.
Auto Commit의 경우 rollback을 사용할수가 없으니(자동으로 commit을 하여 수정을 받아들이고 종료했으니까요...)
데이터 변경이 잘못된거라면 백업 받은것을 리스토어 하거나 반대의 작업을 다시 해주는 수밖에 없습니다.

이렇게 begin tran을 사용하여 트랜잭션을 선언하는 것을 명시적 트랜잭션이라고 합니다.
이번에는 암시적 트랜잭션을 살펴보도록 하겠습니다.

  
  set implicit_transactions on 하면 이제부터는 begin tran을 붙이지 않더라도 데이터 수정이나 삭제 작업이
일어나면 자동으로 트랜잭션이 시작됩니다.
Update를 하고나서 다음에 select를 통해서 트랜잭션 횟수를 확인한 상태입니다.
@@trancount는 현재 트랜잭션의 갯수를 표시해줍니다.
begin tran을 하지 않았는데도 자동적으로 트랜잭션이 시작되었지요?
사용자는 마지막에 이에 대해 commit 이나 rollback을 지정해주면 됩니다.
(다시 명시적 트랜잭션 모드로 돌아갈려면 set implicit_transactions off 해주세요.)
암시적 트랜잭션은 서버 등록정보에서도 지정해줄수 있습니다.
  Implicit transactions에다 체크해주시면 됩니다.
(자, 이제부터 저는 명시적 트랜잭션 모드에서 작업합니다.)

만약 트랜잭션안의 작업이 너무 길다면?
마지막에 하나 잘못했다고 지금까지의 모든 작업을 싸그리 취소시켜야 될까요?
그럴때는 save tran이란 것을 사용하여 트랜잭션 분기점을 설정합니다.
  값이 모두 Update된 상태로 나왔지요?
근데 여기서 deptno가 바뀌어져서는 안되는데...
어떻게 할까요?
다 취소되어야 하나요?
 
  여기서 마지막 save tran fourth_t를 되돌린다고 선택하신분은 오답입니다.
각기 분기점은 begin tran에서 first_t이 하나, first_t에서 secon_t 까지가 하나... 이런 식으로 각 tran사이가
하나의 분기점이 됩니다.
고로 deptno를 20으로 Update한것을 취소하려면 third_t를 취소시켜야 합니다.

마지막으로 트랜잭션 내에 또 트랜잭션이 있는 경우.
이런 경우는 어떻게 될까요...
 
  아무리 사이에 있는 것이 commit이 되었다 할지라도 마지막에 전체 트랜잭션이 rollback되었으므로
값의 변경은 없습니다.
다음을 보시지요...
 
  이번에는 3개의 중첩 트랜잭션 중에서 commit, rollback, commit 순입니다.
얼핏 생각하기에는 presidant로 변경하는 것만 될것같은데 실제는 그렇지 않습니다.
역시 모든 트랜잭션이 취소됩니다.
 
  아무 값도 변하지 않았지요?


개인적으로는 MS-SQL의 Auto Commit 상당히 맘에 안듭니다.
데이터를 잘못해서 변경했을시 트랜잭션이 자동으로 commit되기 때문에 되돌리기가 힘듭니다.
앞으로 Update하거나 Delete등 데이터 수정 작업을 하실때는 꼭 트랜잭션을 명시하시고 작업하시기 바랍니다.
트랜잭션 명시가 여러분의 수호천사가 될지도 모릅니다. ^^
반응형
댓글