MSSQL에서 트랜잭션을 너무 오래 열어두면 어떤 효과가 있습니까?


11

DB에서 트랜잭션을 시작하고 커밋 또는 롤백하는 것을 잊어 버린 경우 어떻게되는지 궁금합니다. 서버가 다운됩니까? 3 일 동안 그대로 두었다고합시다.

다른 사용자가 닫히지 않은 트랜잭션이 있음을 알지 못한다고 가정하고이를 사용하는 사용자도 있습니다 (사용자가 데이터베이스에 데이터를 삽입하고 있다고 가정 해 봅시다). 이 행동의 결과는 무엇입니까?

답변:


14

공개 거래 자체만으로도 결과는 거의 없습니다. 간단한

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

최악의 경우 몇 바이트의 상태 값을 보유합니다. 별거 아냐

대부분의 프로그램은 트랜잭션 내에서 실제 작업을 수행하며 이는 또 다른 문제입니다. 트랜잭션의 요점은 다른 사용자가 동일한 데이터베이스에 동시에 쓰는 경우에도 데이터베이스 내의 여러 사실이 동시에 사실임을 확신 할 수 있다는 것입니다.

은행 계좌간에 송금하는 정식 예를 들어보십시오. 시스템은 소스 계정이 존재하고, 충분한 자금이 있고, 대상 계정이 존재하며, 차변 및 대변이 발생하거나 발생하지 않도록해야합니다. 다른 거래가 발생하는 동안 (이 두 계정 간에도)이를 보장해야합니다. 시스템은 관련 테이블 을 잠금 으로써이를 보장합니다 . 어떤 잠금이 취해지고 얼마나 많은 다른 사람들의 작업이 보이는지는 트랜잭션 격리 수준에 의해 제어됩니다 .

따라서 많은 작업을 수행하면 잠금을 보유한 오브젝트를 기다리는 다른 트랜잭션이 대기 할 가능성이 높습니다. 이렇게하면 시스템의 전체 처리량이 줄어 듭니다. 결국 시간 초과 한계에 도달하고 실패 할 것이며 이는 전체 시스템 동작에 문제가됩니다. 낙관적 격리 수준을 사용하면 다른 사람의 작업으로 인해 커밋을 시도 할 때 트랜잭션이 실패 할 수 있습니다.

고정 잠금은 시스템 리소스를 사용합니다. 이것은 시스템이 다른 요청을 처리하는 데 사용할 수없는 처리량을 감소시키는 메모리입니다.

많은 작업이 수행 된 경우 시스템은 잠금 에스컬레이션 을 수행하도록 선택할 수 있습니다 . 개별 행을 잠그는 대신 전체 테이블이 잠 깁니다. 그러면 더 많은 동시 사용자가 영향을 받고 시스템 처리량이 더 떨어지며 응용 프로그램의 영향이 커집니다.

데이터 변경 사항은이를 보호하는 잠금과 마찬가지로 로그 파일에 기록됩니다. 트랜잭션이 커밋 될 때까지 로그에서 지울 수 없습니다. 따라서 매우 긴 트랜잭션으로 인해 관련된 문제점으로 인해 로그 파일이 팽창 할 수 있습니다.

현재 작업에서 대규모 워크로드에 적합한 tempdb를 사용하는 경우 트랜잭션이 끝날 때까지 리소스가 연결될 수 있습니다. 극단적 인 경우 더 이상 다른 작업을 수행 할 공간이 없기 때문에 실패 할 수 있습니다. 잘못 코딩 된 UPDATE가 tempdb를 채우는 경우가 있었으므로 보고서의 SORT에 디스크가 부족하여 보고서가 실패했습니다.

트랜잭션을 롤백하도록 선택하거나 시스템이 실패하여 복구하는 경우 시스템을 다시 사용할 수있게되는 데 걸리는 시간은 수행 된 작업량에 따라 다릅니다. 단순히 트랜잭션을 연다 고해도 복구 시간에는 영향을 미치지 않으며 수행 된 작업량입니다. 트랜잭션이 열려 있지만 1 시간 동안 유휴 상태 인 경우 거의 즉각적으로 복구됩니다. 그 시간 동안 지속적으로 글을 쓰는 경우 경험에 의하면 복구 시간도 약 1 시간이됩니다.

보시다시피 긴 트랜잭션은 문제가 될 수 있습니다. OLTP 시스템의 경우 모범 사례는 비즈니스 트랜잭션 당 하나의 데이터베이스 트랜잭션을 갖는 것입니다. 빈번한 커밋과 함께 블록으로 일괄 작업 프로세스 입력 및 논리 로직 재시작. 일반적으로 단일 DB 트랜잭션 내에서 수천 개의 레코드를 처리 할 수 ​​있지만 동시성 및 resoruce 소비에 대해 테스트해야합니다.

다른 극단으로 가고 싶은 유혹을 느끼지 말고 거래와 잠금을 완전히 피하십시오. 데이터 내에서 일관성을 유지해야하는 경우 (및 데이터베이스를 사용하는 이유는 무엇입니까?) 격리 수준과 트랜잭션은 매우 중요한 목적을 제공합니다. 옵션에 대해 배우고 응용 프로그램의 각 부분에 따라 사용할 수있는 동시성과 정확성의 균형을 결정하십시오.


3 일 동안 문을 열어도
JanLeeYu

그렇습니다, 심지어 3 일 동안. 중요한 점은 TX가 열린 시간뿐만 아니라 TX가 열린 동안 수행 된 작업량입니다. 물론 DBA로서 트랜잭션 소유자에게 왜 오랫동안 열려야 하는지를 물어볼 수 있습니다. DBA 팀을 운영 할 때 30 분 이상 열려 있고 소유자와 대화 한 모든 TX를 기록했습니다.
Michael Green

확인. 훌륭한 설명 감사합니다. 모두가 훌륭하게 행동했지만.
JanLeeYu 2016 년

안 도심 ... 답장을 다시 한번 감사드립니다.
JanLeeYu

"잘못 코딩 된 업데이트"예. 이것을 보았습니다. 루프 내에서 일부 이름을 한정하지 않고 1 = 1과 같은 동작을 초래하는 업데이트 명령문은 루프의 모든 반복에 대해 전체 테이블을 업데이트했습니다 (이는 대부분의 행에도 잘못된 데이터를 넣습니다).
jpmc26 2016 년

6

가장 큰 결과는 트랜잭션에 사용 된 개체를 차단하는 것입니다. 특히 사용자가 데이터를 삽입한다고 가정하면 장기 실행 트랜잭션에는 일반적으로 사용되는 테이블에 SELECT 문이 포함될 수 있습니다. 사용자의 업데이트 설명이 업데이트 또는 삽입을 완료하는 데 필요한 잠금을 얻지 못할 수 있습니다.

발생할 수있는 두 번째 일은 로그 파일 활동입니다. 예를 들어 큰 데이터 세트를 업데이트하는 경우 트랜잭션이 사용중인 로그 부분은 해당 트랜잭션 기간 동안 활성 상태로 유지됩니다. 트랜잭션이 커밋되거나 롤백 될 때까지 해당 부분을 재사용 할 수 없습니다. 활발하게 활동중인 OLTP 시스템에있을 수있는 시나리오에서는 저장 장치를 채우면서 로그 파일이 빠르게 커질 수 있습니다.


예를 들어, 거래를 만든 사람이 서버에서 연결이 끊어졌을 때 거래를 닫기 위해 서버에 다시 로그인 할 수 있습니까?
JanLeeYu

트랜잭션이 MSDTC를 사용하는 환경에있는 경우 분리 된 트랜잭션 일 수 있습니다. 이 경우 더 이상 사용자가 직접 닫을 수 없으며 DBA가이를 처리해야합니다. 그 외에는 일반적으로 SQL Server가 연결을 끊을 때 트랜잭션이 취소되지만 매번 그렇지 않을 수있는 큰 트랜잭션에서는 다시 취소됩니다.

이 경우 관리자는 여전히 거래를 닫을 수 있습니까?
JanLeeYu

나는 그 하나에 대답 할 수 없다. 그것은 모두 달려있다. 서버를 다시 시작해야하거나 인스턴스가 보조 노드 / 복제본으로 장애 조치 된 경우가있었습니다.

4

불완전한 트랜잭션은 많은 수의 잠금을 보유하고 차단을 일으킬 수 있습니다

트랜잭션이 완료되기 위해 COMMIT 또는 ROLLBACK 문을 발행하지 않고 트랜잭션이 중간에 쿼리가 시간 초과되거나 일괄 처리가 취소되어 트랜잭션이 완료되지 않으면 트랜잭션이 열린 상태로 유지되고 해당 트랜잭션 중에 획득 된 모든 잠금이 계속됩니다. 개최되는. 동일한 연결에서 실행 된 후속 트랜잭션은 중첩 트랜잭션으로 처리되므로 이러한 완료된 트랜잭션에서 획득 한 모든 잠금이 해제되지 않습니다. 이 문제는 ROLLBACK이 실행될 때까지 동일한 연결에서 실행 된 모든 트랜잭션에서 반복됩니다. 결과적으로 많은 수의 잠금이 유지되고 사용자가 차단되며 트랜잭션이 손실되어 예상 한 것과 다른 데이터가 생성됩니다.

출처


예를 들어, 거래를 만든 사람이 서버에서 연결이 끊어졌을 때 거래를 닫기 위해 서버에 다시 로그인 할 수 있습니까?
JanLeeYu

SQL Server는 연결이 끊어진 것을 알고 트랜잭션을 롤백합니다. dba.stackexchange.com/questions/47404/…를 참조하십시오 . 동일한 사용자가 다시 연결하면 다른 세션이되므로 이전 트랜잭션을 어떻게 든 "적용"할 수 없습니다.
Michael Green
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.