Tôi đang làm việc trên một chương trình phát hành DDL. Tôi muốn biết liệu CREATE TABLE
DDL và các DDL tương tự có thể được khôi phục lại
- Postgres
- MySQL
- SQLite
- et al
Mô tả cách mỗi cơ sở dữ liệu xử lý các giao dịch với DDL.
Tôi đang làm việc trên một chương trình phát hành DDL. Tôi muốn biết liệu CREATE TABLE
DDL và các DDL tương tự có thể được khôi phục lại
Mô tả cách mỗi cơ sở dữ liệu xử lý các giao dịch với DDL.
Câu trả lời:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis cung cấp tổng quan về vấn đề này từ quan điểm của PostgreSQL.
DDL có được giao dịch theo tài liệu này không?
SQLite dường như cũng có DDL giao dịch. Tôi đã có thể viết ROLLBACK
một CREATE TABLE
câu lệnh trong SQLite. CREATE TABLE
Tài liệu của nó không đề cập đến bất kỳ 'gotchas' giao dịch đặc biệt nào.
PostgreSQL có DDL giao dịch cho hầu hết các đối tượng cơ sở dữ liệu (chắc chắn là bảng, chỉ số, v.v. nhưng không phải cơ sở dữ liệu, người dùng). Tuy nhiên trên thực tế, bất kỳ DDL nào cũng sẽ bị ACCESS EXCLUSIVE
khóa đối tượng đích, khiến nó hoàn toàn không thể truy cập được cho đến khi giao dịch DDL kết thúc. Ngoài ra, không phải tất cả các tình huống đều được xử lý hoàn hảo - ví dụ: nếu bạn cố gắng chọn từ bảng foo
trong khi một giao dịch khác đang bỏ nó và tạo một bảng thay thế foo
, thì giao dịch bị chặn cuối cùng sẽ nhận được lỗi thay vì tìm thấy foo
bảng mới . (Chỉnh sửa: điều này đã được sửa trong hoặc trước PostgreSQL 9.3)
CREATE INDEX ... CONCURRENTLY
là đặc biệt, nó sử dụng ba giao dịch để thêm chỉ mục vào bảng trong khi cho phép cập nhật đồng thời, vì vậy bản thân nó không thể được thực hiện trong một giao dịch.
Ngoài ra, lệnh duy trì cơ sở dữ liệu VACUUM
không thể được sử dụng trong một giao dịch.
foo
trong khi một giao dịch khác đang giảm và tạo lại nó, thì tôi đồng ý với phiên bản cũ hoặc lỗi. Tôi không hài lòng với phiên bản mới, bởi vì nó chưa được cam kết, vì vậy tôi phải không nhìn thấy nó. Tôi không sao với lỗi, vì dù sao thì trong truy cập giao dịch đồng thời, người ta vẫn phải chuẩn bị để bắt đầu lại giao dịch. Nếu lỗi xảy ra thường xuyên hơn mức cần thiết, nó có thể làm giảm hiệu suất, nhưng nó vẫn đúng.
Mặc dù không nói chính xác là "khôi phục", trong Oracle, lệnh FLASHBACK có thể được sử dụng để hoàn tác các loại thay đổi này, nếu cơ sở dữ liệu đã được cấu hình để hỗ trợ nó.
Có vẻ như các câu trả lời khác đã khá lỗi thời.
Kể từ năm 2019:
START TRANSACTION ... COMMIT;
Vì vậy, bạn vẫn không thể khôi phục các câu lệnh DDL trong một giao dịch nếu câu lệnh sau trong cùng một giao dịch không thành công. (Xem lưu ý của nhà phát triển) . mysql.com/doc/refman/8.0/en/… )
Có vẻ như không thể thực hiện được với MySQL , rất ngu ngốc, nhưng đúng ... (theo câu trả lời được chấp nhận)
"Câu lệnh CREATE TABLE trong InnoDB được xử lý như một giao dịch duy nhất. Điều này có nghĩa là ROLLBACK từ người dùng không hoàn tác câu lệnh CREATE TABLE mà người dùng đã thực hiện trong giao dịch đó."
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Đã thử một số cách khác nhau và nó chỉ đơn giản là sẽ không quay trở lại ..
Công việc xung quanh chỉ đơn giản là đặt cờ báo lỗi và thực hiện "thả bảng tblname" nếu một trong các truy vấn không thành công ..