programing

단일 명세서를 둘러싼 트랜잭션은 무엇을 합니까?

elecom 2023. 5. 23. 21:23
반응형

단일 명세서를 둘러싼 트랜잭션은 무엇을 합니까?

한 쌍의 업데이트를 조정하는 데 트랜잭션이 어떻게 유용한지 알고 있습니다.제가 이해하지 못하는 것은 거래에서 단일 명세서를 포장하는 것인데, 이것은 제가 본 것의 90%입니다.사실, 실제 코드에서는 논리적으로 관련된 일련의 트랜잭션을 각각 자신의 트랜잭션으로 포장하는 것이 제 경험에서 더 일반적이지만 전체가 트랜잭션으로 포장되지는 않습니다.

MS-SQL에서 트랜잭션에서 단일 선택, 단일 업데이트, 단일 삽입 또는 단일 삭제를 래핑하면 이점이 있습니까?

저는 이것이 미신적인 프로그래밍이라고 의심합니다.

아무 소용이 없어요.로그가 없는 대량 삽입 또는 테이블 잘라내기와 같은 드문 예외를 제외한 모든 개별 SQL 문은 명시적으로 그렇게 말하든 말든 자동으로 "In a Transaction"이 됩니다.(수백만 개의 행을 삽입, 업데이트 또는 삭제하더라도).

편집: 아래 @Phillip의 의견을 바탕으로 합니다.현재 버전의 SQL Server에서는 대량 삽입 및 잘라내기 테이블조차도 트랜잭션 로그에 일부 데이터를 기록하지만 다른 작업만큼 많이 기록하지는 않습니다.트랜잭션 관점에서 중요한 차이점은 이러한 다른 유형의 작업에서는 수정 중인 데이터베이스 테이블의 데이터가 롤백할 수 있는 상태의 로그에 없다는 것입니다.

이 모든 것은 명령문이 데이터베이스의 데이터에 적용한 변경 사항이 트랜잭션 로그에 기록되어 작업이 실패할 경우 취소할 수 있다는 것을 의미합니다.

"Begin Transaction", "Commit Transaction" 및 "RollBack Transaction" 명령에서 제공하는 유일한 기능은 두 개 이상의 개별 SQL 문을 동일한 트랜잭션에 넣을 수 있는 것입니다.

편집: (마크 주석을 보강하기 위해...) 예, 이것은 "신비주의적" 프로그래밍 때문일 수도 있고, 데이터베이스 트랜잭션의 본질에 대한 근본적인 오해일 수도 있습니다.좀 더 자선적인 해석은 그것이 단지 부적절한 일관성의 과도한 적용의 결과이며 에머슨 완곡어법의 또 다른 예라는 것입니다.

어리석은 일관성은 작은 마음들의 호고블린입니다.
작은 정치가들과 철학자들과 신들이 숭배하는.

Charles Bretana가 말했듯이, "그것은 아무것도 하지 않습니다." -- 이미 행해진 것 외에는 아무것도 하지 않습니다.

관계형 데이터베이스의 "ACID" 요구사항에 대해 들어본 적이 있습니까?이 "A"는 Atomic의 약자로, 명령문이 전체적으로 작동하거나 작동하지 않는다는 것을 의미하며, 명령문이 수행되는 동안 해당 쿼리의 영향을 받는 데이터에 대해 다른 쿼리를 수행할 수 없습니다. BEGIN TRANSACTION / COMMIT은 이 잠금 기능을 여러 명령문이 수행하는 작업으로 "확장"합니다.하나의 진술에 아무것도 추가되지 않습니다.

그러나 데이터베이스 트랜잭션 로그는 항상 데이터베이스가 수정될 때 기록됩니다(삽입, 업데이트, 삭제).이것은 선택사항이 아닙니다. 사람들을 짜증나게 하는 경향이 있는 사실입니다.예, 대량 삽입 및 복구 모드에 대한 이상한 점이 있지만 여전히 기록됩니다.

여기서도 격리 레벨을 삭제합니다.이렇게 하면 개별 명령에 영향을 주지만 선언된 트랜잭션 래핑 쿼리가 "독립 실행형" 쿼리와 다르게 수행되지는 않습니다. (다중 문 선언 트랜잭션에서는 매우 강력하고 매우 위험할 수 있습니다.)또한 "no lock"은 삽입/업데이트/삭제에는 적용되지 않습니다. 이러한 작업에는 항상 잠금이 필요합니다.

트랜잭션에서 단일 문을 래핑한다는 것은 수동 일회성 UPDATE 문을 실행할 때 WHERE 절을 잊어버린 경우 해당 문을 롤백할 수 있다는 것을 의미합니다.그것은 저를 몇 번 구해주었습니다.

예.

--------------------------------------------------------------
CREATE TABLE T1(CPK INT IDENTITY(1,1) NOT NULL, Col1 int, Col2 char(3));
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');
INSERT INTO T1 VALUES (101, 'abc');

SELECT * FROM T1


--------------------------------------------------------------
/* MISTAKE SCENARIO     (run each row individually) */
--------------------------------------------------------------
BEGIN TRAN YOUR_TRANS_NAME_1;   /* open a trans named YOUR_TRANS_NAME_1 */
    UPDATE T1 SET COL2 = NULL;  /* run some update statement */
    SELECT * FROM T1;       /* OOPS ... forgot the where clause */
ROLLBACK TRAN YOUR_TRANS_NAME_1;    /* since it did bad things, roll it back */
    SELECT * FROM T1;       /* tans rolled back, data restored. */



--------------------------------------------------------------
/* NO MISTAKES SCENARIO (run each row individually) */
--------------------------------------------------------------

BEGIN TRAN YOUR_TRANS_NAME_2;
    UPDATE T1 SET COL2 = 'CBA' WHERE CPK = 4;   /* run some update statement */
    SELECT * FROM T1;               /* did it correctly this time */

COMMIT TRAN YOUR_TRANS_NAME_2           /* commit (close) the trans */

--------------------------------------------------------------

DROP TABLE T1

--------------------------------------------------------------

한 가지 가능한 변명은 단일 문이 트리거를 통해 다른 SQL을 실행하게 할 수 있고, 그 안에서 무언가가 손상되지 않도록 보호한다는 것입니다. 하지만 DBMS라면 이미 암묵적인 트랜잭션을 동일한 방식으로 사용할 수 있는 상식을 가지고 있을 것입니다.

제가 생각할 수 있는 또 다른 것은 어떤 API들은 당신이 자동 커밋을 비활성화할 수 있게 해주고, 코드는 만약을 위해 작성된다는 것입니다.

명시적인 거래를 시작하고 발행하는 경우DML문에 의해 잠겨 있는 리소스는 잠긴 상태로 유지되며 수동으로 커밋하거나 롤백할 때까지 트랜잭션 외부에서 문 결과를 볼 수 없습니다.

이것은 당신이 필요로 할 수도 있고 필요하지 않을 수도 있습니다.

예를 들어, 당신은 여전히 그것들을 잠그면서 예비 결과를 외계에 보여주고 싶을 수도 있습니다.

이 경우 첫 번째 트랜잭션이 커밋되기 전에 잠금 요청을 하는 다른 트랜잭션을 시작하여 레이스 상태를 방지합니다.

암시적 트랜잭션은 다음 즉시 커밋되거나 롤백됩니다.DML문이 완료되거나 실패합니다.

SQL Server에는 세션에 대한 자동 커밋을 해제할 수 있는 설정이 있습니다.일부 고객의 경우 기본값이기도 합니다(https://learn.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql?view=sql-server-2017) 참조).

사용하는 프레임워크 및/또는 데이터베이스 클라이언트에 따라 각 명령을 자체 트랜잭션에 넣지 않으면 해당 명령이 모두 기본 트랜잭션으로 일괄 처리될 수 있습니다.트랜잭션에서 각 트랜잭션을 명시적으로 래핑하면 의도가 명확하게 선언되며 자동 커밋에 대한 회사 전체 정책이 없는 경우에는 현재 자동 커밋 설정에 관계없이 프로그래머가 의도한 방식으로 실제로 수행됩니다.

begin tran / commit tran 명령어가 데이터베이스에서 관찰되는 경우(여기서 설명한 바와 같이), 프레임워크가 의심하지 않는 프로그래머를 대신하여 이 명령어를 생성하고 있을 수도 있습니다.(그들의 프레임워크에서 생성된 SQL 코드를 면밀히 검사하는 개발자는 몇 명입니까?

저는 이 질문이 다소 오래된 것임에도 불구하고 여전히 관련이 있기를 바랍니다.

언급URL : https://stackoverflow.com/questions/1171749/what-does-a-transaction-around-a-single-statement-do

반응형