주요 SQL 데이터베이스에서 CREATE TABLE 및 ALTER TABLE 문을 롤백 할 수 있습니까?


108

DDL을 발행하는 프로그램을 작업 중입니다. CREATE TABLE유사한 DDL을 롤백 할 수 있는지 알고 싶습니다 .

  • Postgres
  • MySQL
  • SQLite

각 데이터베이스가 DDL로 트랜잭션을 처리하는 방법을 설명하십시오.


다만,이 스레드를 보완 H2는 또한에 따라, SQL 명령의 대부분을위한 트랜잭션 DDL 문을 지원하지 않습니다 .
Gabriel Paim

답변:


148

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis 는 PostgreSQL의 관점에서이 문제에 대한 개요를 제공합니다.

이 문서에 따르면 DDL 트랜잭션이 있습니까?

  • PostgreSQL-예
  • MySQL-아니요; DDL로 인해 암시 적 커밋이 발생합니다.
  • Oracle Database 11g Release 2 이상-기본적으로 아니요,하지만 에디션 기반 재정의라는 대안이 있습니다.
  • 이전 버전의 Oracle-아니요; DDL로 인해 암시 적 커밋이 발생합니다.
  • SQL Server-예
  • Sybase Adaptive Server-예
  • DB2-예
  • Informix-예
  • Firebird (Interbase)-예

SQLite는 트랜잭션 DDL도 가지고있는 것으로 보입니다. SQLite ROLLBACK에서 CREATE TABLE성명서를 작성할 수있었습니다 . 그 CREATE TABLE문서에는 특별한 트랜잭션 'gotchas'가 언급되어 있지 않습니다.


8
그러나 sqlite 용 기본 Python 드라이버는 트랜잭션 SQL을 방지합니다. bugs.python.org/issue10740
joeforker

따라서 대답은 "예, MySQL 또는 이전 버전의 Oracle을 사용하지 않는 한 롤백 할 수 있습니다."입니다.
rjmunro

아니요, 나열된 데이터베이스 외에 다른 SQL 데이터베이스가 있습니다.
joeforker 2015

3
트랜잭션 DDL 지원 추가에 대한 MariaDB의 미해결 문제가 있습니다 : jira.mariadb.org/browse/MDEV-4259 . 투표 해주세요.
Gili

1
ALTER TABLESQLite 의 다소 제한적인 문도 롤백 할 수 있습니다. 문서에 명시 적으로 언급되어 있지 않습니다 . 언급 된 것은 트랜잭션 내에서 "고급"변경을 수행하는 방법입니다.
Thomas

32

PostgreSQL에는 대부분의 데이터베이스 개체 (확실히 데이터베이스, 사용자가 아닌 테이블, 인덱스 등)에 대한 트랜잭션 DDL이 있습니다. 그러나 실제로 모든 DDL은 ACCESS EXCLUSIVE대상 개체에 대한 잠금을 가져와 DDL 트랜잭션이 완료 될 때까지 완전히 액세스 할 수 없게됩니다. 또한 모든 상황이 제대로 처리되지는 않습니다. 예를 들어 foo다른 트랜잭션이 테이블 을 삭제하고 대체 테이블을 생성하는 동안 테이블에서 선택하려고 foo하면 차단 된 트랜잭션이 새 foo테이블을 찾는 대신 마침내 오류를 받게됩니다 . (편집 : 이것은 PostgreSQL 9.3 이전에 수정되었습니다.)

CREATE INDEX ... CONCURRENTLY 예외적으로 3 개의 트랜잭션을 사용하여 테이블에 인덱스를 추가하는 동시에 동시 업데이트를 허용하므로 트랜잭션에서 자체적으로 수행 할 수 없습니다.

또한 데이터베이스 유지 관리 명령 VACUUM은 트랜잭션에서 사용할 수 없습니다.


foo다른 트랜잭션이 삭제되고 다시 생성되는 동안 테이블에서 선택하려고 하면 이전 버전이나 오류에 대해 OK 라고 주장합니다 . 나는 새 버전이 아직 커밋되지 않았기 때문에 괜찮지 않다. 그래서 나는 그것을 보지 말아야한다. 동시 트랜잭션 액세스에서는 어쨌든 트랜잭션을 다시 시작할 준비가되어 있어야하므로 오류가 있어도 괜찮습니다. 필요한 것보다 더 자주 오류가 발생하면 성능이 저하 될 수 있지만 여전히 정확합니다.
Jan Hudec 2014-06-04

1
@JanHudec : 새 테이블의 커밋되지 않은 버전은 표시되지 않고 삭제 / 재생성 된 전체 트랜잭션의 결과 만 표시됩니다. 즉, 테이블을 삭제, 재생성 및 다시 채우는 트랜잭션은 해당 테이블에서 선택하는 다른 프로세스와 사실상 원자 적입니다. (그러나 모든 것이 즉시 심지어 테이블의 스키마를 읽으려고으로 차단 얻을 것이다)
araqnid

5

엄격히 말해서 "롤백"은 아니지만 Oracle에서 FLASHBACK 명령을 사용하여 데이터베이스가이를 지원하도록 구성된 경우 이러한 유형의 변경을 취소 할 수 있습니다.


5

다른 답변은 꽤 오래된 것 같습니다.

2019 년 현재 :

  • Postgres는 많은 릴리스에 대해 트랜잭션 DDL을 지원했습니다.
  • SQLite는 많은 릴리스에서 트랜잭션 DDL을 지원했습니다.
  • MySQL은 2018 년에 출시 된 8.0부터 Atomic DDL 을 지원했습니다 .

1
MySQL 8의 Atomic DDL은 트랜잭션 문이 아닌 원자 DDL 문을 참조합니다. 원자 적이든 아니든 DDL 문은 대부분 여전히 암시 적 커밋을 유발하므로 다른 트랜잭션 내에서 실행할 수 없습니다 (예 : START TRANSACTION ... COMMIT;동일한 트랜잭션에서 후자의 DDL 문이 실패하면 트랜잭션에서 DDL 문을 롤백 할 수 없습니다 . mysql.com/doc/refman/8.0/en/… )
Lacek

4

MySQL로는 할 수 없습니다 . 매우 멍청한 것처럼 보이지만 사실입니다 ... (허용되는 답변에 따라)

"InnoDB의 CREATE TABLE 문은 단일 트랜잭션으로 처리됩니다. 이는 사용자의 ROLLBACK이 해당 트랜잭션 중에 사용자가 만든 CREATE TABLE 문을 실행 취소하지 않음을 의미합니다."

https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

몇 가지 다른 방법을 시도했지만 단순히 롤백되지 않습니다 ..

해결 방법은 단순히 실패 플래그를 설정하고 쿼리 중 하나가 실패한 경우 "drop table tblname"을 수행하는 것입니다.


1
제길. 지난 한 시간 동안 특정 (만들기) 테이블이 실패 할 때 이전에 생성 된 테이블이 사라지지 않는 이유를 알아 내려고했습니다. MariaDB (XAMPP가 MySQL에서 MariaDB로 전환됨)를 사용하고 있지만 경우는 동일합니다. 이것은 어리 석다 : |
akinuri
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.