트랜잭션을 데이터베이스 (예 : SQL Server)에 커밋하지 않으면 어떻게됩니까?


108

쿼리가 있다고 가정합니다.

begin tran
-- some other sql code

그런 다음 커밋하거나 롤백하는 것을 잊었습니다.

다른 클라이언트가 쿼리를 실행하려고하면 어떻게됩니까?

답변:


148

트랜잭션을 커밋 하거나 롤백 하지 않는 한 여전히 "실행 중"이며 잠재적으로 잠금을 유지합니다.

클라이언트 (응용 프로그램 또는 사용자)가 커밋하기 전에 데이터베이스에 대한 연결을 닫으면 여전히 실행중인 트랜잭션이 롤백되고 종료됩니다.


1
mmm, ok 나는 이것이 일종의 자물쇠를 만드는 것이라고 생각했습니다. 연결을 닫으면 실제로이 상태에서 벗어날 수 있을지 확신하지 못했습니다. 문제는 커밋하려고 할 때 오류가 발생한다는 것입니다. 이제 연결을 닫았고 모두 작동했습니다.
Charbel

12
사이드 참고 : Management Studio를 사용하는 경우, 쿼리 창을 닫으면 연결을 닫습니다
조 필립스

3
@BradleyDotNET : 예, 확실히
marc_s

2
기본적으로 쿼리 창 / 연결을 닫으면 SQL Server Management Studio가 자동 커밋됩니다.
Nuno

1
트랜잭션이 활성 상태 인 동안 클라이언트가 연결을 닫을 때 항상 롤백되지는 않습니다. 이것은 클라이언트와 db에 따라 다릅니다. 예를 들어 Java 앱이 Oracle db에 대한 연결을 닫으면 열려있는 모든 연결이 자동으로 커밋됩니다.
AviD

38

실제로 직접 시도해 볼 수 있으며 이것이 어떻게 작동하는지 느끼는 데 도움이 될 것입니다.

Management Studio에서 두 개의 창 (탭)을 열면 각각 SQL에 대한 자체 연결이 있습니다.

이제 하나의 창에서 트랜잭션을 시작하고 삽입 / 업데이트 / 삭제와 같은 작업을 수행 할 수 있지만 아직 커밋하지는 않습니다. 그런 다음 다른 창에서 데이터베이스가 트랜잭션 외부에서 어떻게 보이는지 볼 수 있습니다. 격리 수준에 따라 첫 번째 창이 커밋 될 때까지 테이블이 잠기거나 다른 트랜잭션이 지금까지 수행 한 작업을 볼 수 (없을) 수 있습니다.

결과에 어떤 영향을 미치는지 확인하기 위해 다양한 격리 수준을 사용하고 잠금 힌트를 사용하지 마십시오.

또한 트랜잭션에서 오류가 발생하면 어떻게되는지 확인하십시오.

이 모든 것들이 어떻게 작동하는지 이해하는 것이 매우 중요합니다. 그렇지 않으면 SQL이하는 일에 여러 번 당황 할 것입니다.

즐기세요! GJ.


그래도 트랜잭션이 최소한 커밋을 실행하기 전에 로그에 기록됩니까? 예를 들어 트랜잭션을 시작하고 커밋을 실행하기 전에 삽입 명령을 실행하고 "다른 작업을 수행"한다고 가정합니다. 내 삽입 명령이 로그에 기록됩니까? 이렇게하면 서버가 커밋을 실행하기 전에 충돌하면 원래 위치로 돌아올 수 있고 나중에 커밋을 실행할 수 있습니다 ( "다른 작업"을 수행 할 때마다).
user1870400

16

트랜잭션은 완전히 실행되거나 전혀 실행되지 않습니다. 트랜잭션을 완료하는 유일한 방법은 커밋하는 것입니다. 다른 방법을 사용하면 롤백이 발생합니다.

따라서 시작하고 커밋하지 않으면 연결이 닫힐 때 롤백됩니다 (트랜잭션이 완료로 표시되지 않고 중단되었으므로).


그래야하지만 항상 그런 것은 아닙니다.
FalcoGer

... 트랜잭션을 지원 하지 않는 mySQL의 MyISAM과 같은 것 입니다.
Piskvor 건물 왼쪽

3

들어오는 트랜잭션의 격리 수준에 따라 다릅니다.

SQL 트랜잭션 격리 설명


6
트랜잭션의 동작은 격리 수준에 의존하지 않습니다. 그들이 야기 할 수있는 잠금의 양이 그렇습니다.
marc_s

연결로 읽을 수있는 데이터는 확실히 격리 수준에 따라 달라집니다. 격리를 READ UNCOMMITTED로 설정 한 경우 아직 커밋되지 않은 데이터를 읽을 수 있으며 실제로 트랙의 특정 지점에서 롤백 될 수 있지만 이렇게하면 잠금이 없습니다. 격리 수준으로 READ COMMITTED가 있으면 커밋되지 않은 행을 읽을 수 없습니다. SNAPSHOT을 사용하지 않으면 두 번째 클라이언트가 중단됩니다.
Xhalent

2

트랜잭션을 열면 아무것도 잠기지 않습니다. 그러나 해당 트랜잭션 내에서 일부 쿼리를 실행하면 격리 수준에 따라 일부 행, 테이블 또는 페이지가 잠기므로 다른 트랜잭션에서 액세스를 시도하는 다른 쿼리에 영향을줍니다.


1

거래 예

tran tt 시작

SQL 문

오류가 발생한 경우 tran tt 롤백 그렇지 않으면 tran tt 커밋

commit tran tt를 실행하지 않는 한 데이터는 변경되지 않습니다.


1
트랜잭션 이름 지정은 MS SQL에서 불필요 할뿐만 아니라 잘못된 제어 감각을 줄 수 있습니다. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Y예를 들어 작동하지 않습니다. 참조 stackoverflow.com/questions/1273376/...

0

잠재적 인 잠금 문제 외에도 활성 트랜잭션에 대한 최소 LSN을 초과하여자를 수 없기 때문에 트랜잭션 로그가 증가하기 시작하고 스냅 샷 격리를 사용하는 경우 tempdb의 버전 저장소가 증가합니다. 비슷한 이유.

를 사용 dbcc opentran하여 가장 오래된 미결 거래의 세부 정보를 볼 수 있습니다 .


0

커밋되지 않은 트랜잭션은 서버를 잠그고 다른 쿼리는 서버에서 실행되지 않습니다. 트랜잭션을 롤백하거나 커밋해야합니다. SSMS를 종료하면 트랜잭션이 종료되어 다른 쿼리를 실행할 수 있습니다.


-4

동작이 정의되지 않았으므로 커밋 또는 롤백을 명시 적으로 설정해야합니다.

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

"자동 커밋 모드가 비활성화되어 있고 명시 적으로 마지막 변경 사항을 커밋하거나 롤백하지 않고 연결을 닫으면 암시 적 COMMIT 작업이 실행됩니다."

Hsqldb가 롤백합니다.

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

결과는

2011-11-14 14 : 20 : 22,519 main INFO [SqlAutoCommitExample : 55] [AutoCommit enabled = false] 2011-11-14 14 : 20 : 22,546 main INFO [SqlAutoCommitExample : 65] [데이터베이스에서 0 # 사용자 발견]


2
이것은 Oracle의 경우에 해당 될 수 있지만 (모르겠습니다) 질문자가 MS-SQL에 대해 묻습니다
PaulG

첫 번째 인용문은 서버가 아닌 JDBC 드라이버에 적용됩니다.
djechlin 2013 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.