[SQL] 나는 커밋 또는 읽기 트랜잭션을 롤백해야 하는가?
SQL나는 커밋 또는 읽기 트랜잭션을 롤백해야 하는가?
나는이 분리 레벨을 지정할 수 있도록 내가 트랜잭션 내에서 실행하는 읽기 쿼리가 있습니다. 쿼리가 완료되면, 어떻게해야합니까?
각 일의 의미는 무엇인가?
using (IDbConnection connection = ConnectionFactory.CreateConnection())
{
using (IDbTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
using (IDbCommand command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandText = "SELECT * FROM SomeTable";
using (IDataReader reader = command.ExecuteReader())
{
// Read the results
}
}
// To commit, or not to commit?
}
}
편집 : 문제는 트랜잭션을 사용해야하는 경우가 아니거나 트랜잭션 레벨을 설정하는 다른 방법이있는 경우. 그것은 아무것도 수정하지 않는 트랜잭션이 커밋 또는 롤백 것이 어떤 차이가 있는지 질문입니다. 성능 차이가 있나요? 그것은 다른 연결에 영향을 미칩니 까? 다른 차이?
해결법
-
==============================
1.당신은 커밋합니다. 기간. 다른 합리적인 대안이 없습니다. 당신이 거래를 시작한 경우, 당신은 그것을 닫아야합니다. 출시 당신이 있었 수있는 잠금을 커밋하고하는 것은 READUNCOMMITTED 또는 직렬화 분리 레벨과 동등하게 합리적이다. 암시 적 롤백에 의존 - 아마 기술적으로 동등한 동안은 - 단지 빈약 한 형태이다.
당신은 커밋합니다. 기간. 다른 합리적인 대안이 없습니다. 당신이 거래를 시작한 경우, 당신은 그것을 닫아야합니다. 출시 당신이 있었 수있는 잠금을 커밋하고하는 것은 READUNCOMMITTED 또는 직렬화 분리 레벨과 동등하게 합리적이다. 암시 적 롤백에 의존 - 아마 기술적으로 동등한 동안은 - 단지 빈약 한 형태이다.
그것이 당신을 확신하지 않은 경우, 당신의 코드의 중간에 UPDATE 문을 삽입하고 발생하고 그 데이터를 제거 암시 롤백을 추적하는 다음 사람을 상상한다.
-
==============================
2.당신은 아무것도 변경하지 않은 경우, 당신은 사용할 수 있습니다 중 하나는 ROLLBACK을 COMMIT 또는. 어느 하나는 귀하가 취득한 모든 읽기 잠금을 해제하고 당신이 다른 변경을하지 않았기 때문에, 그들은 동등 할 것이다.
당신은 아무것도 변경하지 않은 경우, 당신은 사용할 수 있습니다 중 하나는 ROLLBACK을 COMMIT 또는. 어느 하나는 귀하가 취득한 모든 읽기 잠금을 해제하고 당신이 다른 변경을하지 않았기 때문에, 그들은 동등 할 것이다.
-
==============================
3.당신이 트랜잭션을 시작하면, 가장 좋은 방법은 항상 그것을 커밋. 예외가 귀하의 사용 (트랜잭션) 내에서 발생하는 경우 트랜잭션이 자동으로 롤백을합니다 차단합니다.
당신이 트랜잭션을 시작하면, 가장 좋은 방법은 항상 그것을 커밋. 예외가 귀하의 사용 (트랜잭션) 내에서 발생하는 경우 트랜잭션이 자동으로 롤백을합니다 차단합니다.
-
==============================
4.포장 만에서 쿼리를 최적화 고려할 수 JDBC 드라이버를 설정 (그러나, 아무도 있도록하지 않는 당신이 "읽기 전용"으로 트랜잭션을 알 수 있습니다 (특히 자바)로 거래 조회 읽을 이럴 그것은 의미가 있습니다 ) 그럼에도 불구 INSERT를 발행에서 당신을 방지 할 수 있습니다. 예를 들면 오라클 드라이버는 완전히 크게 읽기 기반 응용 프로그램의 성능을 많이 얻게 읽기 전용으로 표시 트랜잭션에 쿼리에 테이블 잠금을 방지 할 수 있습니다.
포장 만에서 쿼리를 최적화 고려할 수 JDBC 드라이버를 설정 (그러나, 아무도 있도록하지 않는 당신이 "읽기 전용"으로 트랜잭션을 알 수 있습니다 (특히 자바)로 거래 조회 읽을 이럴 그것은 의미가 있습니다 ) 그럼에도 불구 INSERT를 발행에서 당신을 방지 할 수 있습니다. 예를 들면 오라클 드라이버는 완전히 크게 읽기 기반 응용 프로그램의 성능을 많이 얻게 읽기 전용으로 표시 트랜잭션에 쿼리에 테이블 잠금을 방지 할 수 있습니다.
-
==============================
5.중첩 된 트랜잭션을 고려하십시오.
중첩 된 트랜잭션을 고려하십시오.
대부분의 RDBMS에서 중첩 된 트랜잭션을 지원하거나, 매우 제한적인 방법으로 그들을 모방하려고하지 않습니다.
예를 들어, MS SQL 서버에서, 내부 거래 롤백 (실제 거래가 아닌, MS SQL 서버는 트랜잭션 수준을 계산!) (실제 거래 인) 최 트랜잭션에 일어났던 모든 롤백됩니다.
일부 데이터베이스 래퍼는 최 트랜잭션이 커밋 또는 다시 압연 여부에 관계없이, 최 거래에 오류가 발생했습니다 것을 기호 및 롤백 모든으로 내부 트랜잭션 롤백을 고려할 수 있습니다.
A는 COMMIT 그래서 당신이 당신의 구성 요소가 일부 소프트웨어 모듈에 의해 사용되는 것을 배제 할 수있는 안전한 방법이다.
이 질문에 대한 일반적인 대답 있습니다. 코드 예제는 독창적 인 새로운 데이터베이스 연결을 열어 외부 트랜잭션과 문제를 해결 작동합니다.
성능에 관하여 : 분리 레벨에 따라 선택한다 자물쇠 및 임시 데이터 (스냅)의 변화 정도를 필요로 할 수있다. 트랜잭션이 종료 될 때이 정리되어있다. COMMIT 또는 ROLLBACK을 통해 이루어집니다 여부를 중요하지 않습니다. A는 (두 문자 이하)를 ROLLBACK 이상의 구문 분석에 아마 빠른 COMMIT 및 기타 사소한 차이 -가 보낸 CPU 시간의 사소한 차이가있을 수 있습니다. 분명히, 이것은 읽기 전용 작업 만 사실이다!
롤백 오류 상태를 의미한다고 가정 수있는 코드를 읽을 수 있습니다 다른 프로그래머 : 완전을 요구하지.
-
==============================
6.그냥 보조 노트,하지만 당신은 또한 같은 그 코드를 작성할 수 있습니다 :
그냥 보조 노트,하지만 당신은 또한 같은 그 코드를 작성할 수 있습니다 :
using (IDbConnection connection = ConnectionFactory.CreateConnection()) using (IDbTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted)) using (IDbCommand command = connection.CreateCommand()) { command.Transaction = transaction; command.CommandText = "SELECT * FROM SomeTable"; using (IDataReader reader = command.ExecuteReader()) { // Do something useful } // To commit, or not to commit? }
그리고 당신이 경우 다시 구조 상황이 조금 당신이 아니라 상단에 IDataReader에의 사용 블록을 이동할 수 있습니다 비트.
-
==============================
7.당신은 저장 프로 시저로 SQL을 넣고 쿼리 이상이를 추가하는 경우 :
당신은 저장 프로 시저로 SQL을 넣고 쿼리 이상이를 추가하는 경우 :
set transaction isolation level read uncommitted
다음은 C # 코드에 어떤 농구를 통해 점프 할 필요가 없습니다. 저장 프로 시저에서 트랜잭션 격리 수준을 설정하면 설정 (연결 풀링되기 때문에 다른 설정에 대해 걱정할 필요가 뭔가입니다) 해당 연결의 모든 미래 용도에 적용되지는 않습니다. 저장 프로 시저의 말에 그냥 연결이로 초기화 된 어떤로 돌아갑니다.
-
==============================
8.ROLLBACK은 대부분 오류 또는 예외적 인 상황의 경우에 사용하고, 성공적으로 완료의 경우 COMMIT된다.
ROLLBACK은 대부분 오류 또는 예외적 인 상황의 경우에 사용하고, 성공적으로 완료의 경우 COMMIT된다.
우리는 심지어 중요하지 않는 것 읽기 전용 트랜잭션의 경우, (성공) COMMIT과 (실패) ROLLBACK와의 거래를 닫아야합니다. 사실 그것은 일관성과 미래 교정을 위해, 문제 않습니다.
읽기 전용 트랜잭션은 논리적으로 예를 들어 여러 가지 방법으로 "실패"할 수 있습니다 :
COMMIT과 ROLLBACK은 읽기 전용 트랜잭션에 대해 적절하게 사용하는 경우 예상대로 DB 쓰기 코드는, 예를 들어, 어떤 시점에 추가되면, 그것은 계속 작동합니다 캐싱, 감사 또는 통계.
암시 적 ROLLBACK은 "심각한 오류"상황에 사용되어야 할 때 등을 복구 할 수없는 오류, 네트워크 오류, 정전와 응용 프로그램이 충돌 또는 종료
-
==============================
9.읽기가 상태를 변경하지 않는 것을 감안할 때, 나는 아무것도 할 수 없을 것입니다. A는, 아무것도하지 않고 데이터베이스에 대한 요청을 보내주기를 낭비 사항을 제외하고, 커밋 수행. 당신은 상태를 변경 작업을 수행하지 않았습니다. 마찬가지로 롤백.
읽기가 상태를 변경하지 않는 것을 감안할 때, 나는 아무것도 할 수 없을 것입니다. A는, 아무것도하지 않고 데이터베이스에 대한 요청을 보내주기를 낭비 사항을 제외하고, 커밋 수행. 당신은 상태를 변경 작업을 수행하지 않았습니다. 마찬가지로 롤백.
당신은 그러나 당신의 개체를 정리하고 데이터베이스에 연결을 종료해야합니다. 아니이 코드가 반복적으로 호출되는 경우 문제가 발생할 수 있습니다 연결을 닫는.
-
==============================
10.당신은 YES 자동 커밋 거짓을 설정합니다.
당신은 YES 자동 커밋 거짓을 설정합니다.
JDBC (PostgreSQL의 드라이버)와 실험, 나는 선택 쿼리 나누기 (때문에 타임 아웃), 당신은 새로운 선택 쿼리를 시작할 수 없습니다 경우 롤백하지 않는 것을 발견했다.
-
==============================
11.당신은 당신의 코드 샘플에서는
당신은 당신의 코드 샘플에서는
그렇지 않은 경우, ...는 "읽기"거래 같은 건 없다 만 ... 인서트, 업데이트 및 삭제 문 (데이터를 변경할 수 있습니다 문) 트랜잭션에 변경 사항 무슨 소리하는 잠금 즉 SQL 데이터에 서버 박았 당신 때문에 해당 데이터에 영향을주는 기타 거래의, 읽고있다. 이 잠금의 수준은 SQL 서버 격리 수준에 따라 달라집니다.
하지만 당신은 커밋 할 수없는, 또는 롤백 아무것도, 당신의 SQL 문이 변경되지 않은 경우 아무것도.
데이터를 변경하는 경우, 당신은 명시 적으로 transation를 시작하지 않고 분리 레벨을 변경할 수 있습니다 ... 모든 개인 SQL 문은 트랜잭션에서 암시 적이다. 명시 적으로 트랜잭션을 시작하는 2 개 이상의 문이 동일한 트랜잭션 내에 있는지 확인하기 위해에만 필요합니다.
당신이 원하는 모든 트랜잭션 격리 수준을 설정하면, 그냥 (어떤 수준 당신이 원하는 또는) "설정 트랜잭션 격리 수준 반복 읽기"에 명령의의 CommandText를 설정 CommandType.Text에 CommandType을 설정하고 명령을 실행합니다. (당신은) (Command.ExecuteNonQuery를 사용할 수 있습니다)
참고 : 여러 명령문을 읽을하고, 그리고 그들 모두를하려는 경우에 당신은 분리 레벨 상단 반복 읽기 또는 직렬화를 설정해야합니다, 첫 번째로 데이터베이스의 동일한 상태 "를 참조하십시오"...
-
==============================
12.당신은 동일한 데이터를 읽는 다른 사람을 차단해야합니까? 왜 트랜잭션을 사용합니까?
당신은 동일한 데이터를 읽는 다른 사람을 차단해야합니까? 왜 트랜잭션을 사용합니까?
@Joel는 - 내 질문은 더 잘 표현한 것 "읽기 쿼리를 사용하는 이유 거래?"
@Stefan은 - 당신이 저장된 프로 시저를의 Ad-Hoc SQL을 사용하려고하고 있지 않은 경우, 다음 단지 쿼리에서 테이블 후 WITH (NOLOCK)를 추가합니다. 응용 프로그램에서 (최소이기는하지만) 오버 헤드 및 트랜잭션에 대한 데이터베이스를 부과 해달라고이 방법.
SELECT * FROM SomeTable WITH (NOLOCK)
주석 3 @ 편집 : 당신이 질문 태그에 "SQLSERVER"을 가지고 있기 때문에, 나는에서 MSSQLServer 가정 한 대상 제품이었다. 이제 그 시점이 명확하게 된 것을, 나는 특정 제품 참조를 제거하려면 태그를 편집했습니다.
나는 당신이 처음부터 읽기 연산에 트랜잭션을 만들고 싶어 왜 아직 아닙니다.
from https://stackoverflow.com/questions/309834/should-i-commit-or-rollback-a-read-transaction by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 는 SQL Server 2008의 테이블에 Excel 스프레드 시트에서 데이터를 내보내는 방법 (0) | 2020.06.02 |
---|---|
[SQL] SQLite는 :으로 선택? (0) | 2020.06.02 |
[SQL] SQL에서 여러 열을 업데이트 (0) | 2020.06.02 |
[SQL] 교리와 원시 SQL을 사용하여 (0) | 2020.06.02 |
[SQL] 어떻게 엑셀 2005 개 데이터를 전송하거나 수출 SQL 서버 않습니다 (0) | 2020.06.02 |