트랜잭션 간단 정리
그냥 간단하게 남기려고 쓴다
주 내용은 서비스개발실 SQL Server 책이랑 SQL 전문가 가이드 내용을 보고 남긴다. Head First SQL 보고 추가할 내용이 있으면 수정한다.
트랜잭션이란?
- 처리하는 작업의 논리적인 처리 단위
- 작업 단위는 그것을 구성하는 세부적인 작업의 연산(더하기 빼기 등등)들의 집합
- 데이터베이스 응용 프로그램을 트랜잭션 들의 집합으로도 볼 수있다고 한다 (기능 하나하나가 트랜잭션이라고 볼 때)
트랜잭션을 이해해야 하는 이유
- 불필요한 잠금을 피하고 잠금(Lock)을 원천적으로 피할 수 없지만 최대한으로 관리하기 위해서
트랜잭션의 범위
- 트랜잭션 하나에 데이터 처리작업(입력, 수정, 삭제) 하나가 포함될 수도 있고 처리작업 여러개가 하나의 묶음으로 포함될 수 있다
All of Nothing
- 말 그대로 여러데이터를 변경할 때 변경 처리가 모두 완료되거나 아니면 일부가 처리되지 못하면 이미 처리된 작업마저 취소해서 전부 되거나 전부 안되거나 그런 말이다.
4대 속성
- 원자성 : All of nothing
- 일관성 : 트랜잭션이 완료된 데이터는 일관되게 유지되어야 하는 것
- 격리성 : 동시에 트랜잭션이 실행될 때 서로간에 간섭하지 않는 것
- 영속성 : 트랜잭션이 완료된 데이터베이스 변경사항이 영구적으로 저장되는 것
TCL(Transaction control language)
- Commit : 올바르게 반경된 데이터를 데이터베이스에 반영시키는 것
- Rollback : 트랜잭션 시작 이전의 상태로 되돌리는 것
- Savepoint : 데이터 변경을 사전에 지정한 저장점 까지만 롤백하라는 것
트랜잭션의 대상
- UPDATE, INSERT, DELETE등 데이터를 수정하는 DLM문
- SELECT 문은 직접적인 트랜잭션의 대상이 아니지만 SELECT FOR UPDATE 등 배타적 LOCK을 요구하는 SELECT 문장은 트랜잭션의 대상이 된다고 한다
--> 나중에 Lock 정리할 때 내용 추가
Commit이나 Rollback 이전의 데이터 상태
- 메모리 Buffer에만 저장되어 있어서 데이터의 변경 이전 상태로 복구 가능
- 현재 사용자가 SELECT 문장으로 결과를확인 가능 (이런건 테스트 해보자)
- 다른 사용자는 현재 사용자가 수행한 명령의 결과를 볼 수 없다 (Lock?)
- 변경된 행은 잠금(Lock)이 설정되어서 다른 사용자가 변경할 수 없다.
Commit 이후의 데이터 상태
- 데이터에 대한 변경 사항이 데이터베디읏에 반영된다
- 이전 데이터는 영원히 잃어버린다.
- 모든 사용자는 결과를 볼 수 있다
- 관련된 행에 대한 잠금(Lock)이 풀리고 다른 사용자들이 행을 조작할 수 있게 된다
Auto Commit (이놈은 트랜잭션이냐... 아니냐...)
- SQL Server 기본값
- DDL, DML 수행시 DBMS가 트랜잭션을 컨트롤하는 방식 명령어가 성공적으로 수행되면 Auto Commit이 되고 오류가 발생하면 Rollback을 자동으로 수행
암시적 트랜잭션
- Oracle 기본 값
- 트랜잭션의 시작은 DBMS가 처리하고 트랜잭션의 끝은 사용자가 명시적으로 Commit 또는 Rollback으로 처리하는 것
- 인스턴스(데이터베이스 자체 연결??)나 세션 단위(사용자 단위????)로도 설정할 수 있다????
명시적 트랜잭션
- 트랜잭션의 시작과 끝을 사용자가 명령어를 써서 지정하는 방식
- BEGIN TRAN ~~~~ COMMIT or ROLLBACK
Commit과 Rollback 으로 얻는 효과
- 데이터 무결성 보장 (명령이 실행되어야만 반영되고 트랜잭션의 고립성 특성으로 데이터 접근이 제어되기 때문)
- 영구적인 변경을 하기 전에 데이터의 변경사항 확인 가능(이건 현재 사용자만 가능할 듯 다른 사용자는 안 됨)
- 논리적으로 연관된 작업을 그룹핑하여 처리 가능 (작업 내부의 세부적인 연산을 처리한다는 말과 같은 말)
트랜잭션 주의사항
- Create, Alter, Drop, Rename, Truncate 등 DDL 문장을 실행하면 그 전후 시점에 자동으로 커밋된다
- DML 이후에 DDL이 수행되면 DDL 수행전에 자동으로 커밋된다는 말이다
- 데이터베이스를 정상적으로 접속을 종료시키면 자동으로 트랜잭션이 커밋된다.
- 어플리케이션의 이상 종료로 데이터베이스와의 접속이 단절되면 트랜잭션이 자동으로 롤백된다 (진짜????? connection이 어떻게 관리되는데???)
트랜잭션의 개수
- 트랜잭션 카운트라는 것이 있다 MS SQL에서는 @@TRANCOUNT 라는 것이 있어서 현재 BEGIN TRAN이 몇개나 있는지 알 수있다
예를들면 중첩 트랜잭션을 보면 이해가 쉽다
BEGIN TRY
BEGIN TRAN
SELECT @@TRANCOUNT -- 1
BEGIN TRAN
SELECT @@TRANCOUNT -- 2
SELECT TOP 1 * FROM sys.sysobjects
ROLLBACK TRAN
SELECT @@TRANCOUNT -- 0
COMMIT TRAN -- error
SELECT @@TRANCOUNT -- 0
END TRY
BEGIN CATCH
END CATCH
출처: http://ddoung2.tistory.com/178 [DDoung2]
뭐 저렇다는 것인데 저건 예시고 실제로는 .NET의 C# 코드에서 한번 DBMS가 실행하는 SP에서 한번이상 이런 식으로 BEGIN TRAN을 할 수 있다.
아래 훈스닷넷 커뮤니티에 예시가 잘되어 있는데
http://ucclight.hoons.net/Board/qacshap/Content/97132
여기서 보면 C# 코드에서는 TransactionScope로 트랜잭션을 시작했고 SP안에도 Begin Tran이 있다 즉, TRANCOUNT가 2가 되는 것인데
위의 중첩 트랜잭션 예시는 Try로 감싸서 오류가 나도 예외처리가 된다 Try를 제거하면 두 번의 트랜잭션이 시작되고 Rollback이 되면서 TRANCOUNT가 0이 되고 나서 다시 COMMIT 을 하게 되니 트랜잭션 처리할 것이 없는데 처리하라고 해서 생기는 오류가 난다
훈스닷넷의 예시를 보면 Code에서 시작한 트랜잭션이 SP 스크립트 안에서도 트랜잭션이 동작하면서 관리가 양쪽에서 다하니 힘들어지는?? Code, SP 양쪽에서 관리 한다니 ㅠㅠ 어쨌든 error가 나는 case이고 이것에 대한 트랜잭션 개수는 좀 더 정확히 파악해서 테스트를 하도록 한다
또 한가지... Auto Commit이 일어 날 때 뭐가 달라지는 지 확인해 보자.. 어렵다 Auto Commit은 개수를 무시해야 하나???
어쨌든 훈스닷넷 예시에서는 기본적으로 트랜적션은 프로그램으로 하실꺼면 프로그램에서만 프로시저에서 할꺼면 프로시저에서만 하시는걸 추천드립니다.
이렇게 말 하고 있다 그리고
개인적으론 특별한 경우가 아니면 프로시져에서만 합니다. 한쪽에서 하지 않으면 논리적인 오류가 날 가능성이 매우 큽니다.그리고 추적역시 쉽지 않지요. 그리고 프로그램에서 하실꺼면 .net2.0 이상이면 TransactionScope로 싸시는걸 추천드립니다.
이렇게 자신의 추천하는 방법도 제시해 주고 있다.
약간 정답이 없는 문제이다. 모든 트랜잭션을 SP내부에 위임할 수도 있고 코드로 제어하는 것이 좋아서 .NET에서 TransactionScope나 ITransaction 인터페이스를 사용해 구현한 UnitOfWork(라이브러리 아님 커넥션 하나에서 트랜잭션을 처리하는 패턴 같음(회사에서 사용)) 에서 트랜잭션 관리를 위임할 수 있는 선택의 문제가 같이 있다
어짜피 코드가 좋을지 SP에서가 좋을지 판단할 만한 경험이나 통찰력이 부족하다 일단 양쪽에 다 Transaction 관리가 된다는 것만 이해하고 나중에 개념을 업그레이드 시켜보자.
기본적인 내용은 여기까지!!!
'Computer Science > 데이터베이스' 카테고리의 다른 글
친절한 SQL 튜닝 1. SQL 처리과정과 I/O (0) | 2018.07.04 |
---|---|
옵티마이저 (0) | 2018.04.13 |
트랜잭션 매니저와 카운트 그리고 Biz (0) | 2018.03.25 |
Entity Framework와 Code First (2) | 2018.03.20 |
집합으로 표현한 SQL JOIN (0) | 2017.10.26 |