Điều gì xảy ra nếu bạn không thực hiện một giao dịch với cơ sở dữ liệu (ví dụ, SQL Server)?


108

Giả sử tôi có một truy vấn:

begin tran
-- some other sql code

Và sau đó tôi quên cam kết hoặc quay trở lại.

Nếu một máy khách khác cố gắng thực hiện một truy vấn, điều gì sẽ xảy ra?

Câu trả lời:


148

Miễn là bạn không CAM KẾT hoặc QUAY LẠI một giao dịch, giao dịch đó vẫn đang "chạy" và có khả năng bị khóa.

Nếu khách hàng của bạn (ứng dụng hoặc người dùng) đóng kết nối với cơ sở dữ liệu trước khi cam kết, mọi giao dịch vẫn đang chạy sẽ được khôi phục và chấm dứt.


1
mmm, ok, tôi nhận ra điều này đang tạo ra một số loại khóa. Tôi không chắc rằng việc đóng kết nối sẽ thực sự giúp tôi thoát khỏi trạng thái này. vấn đề là tôi đã gặp lỗi khi cố gắng cam kết. bây giờ tôi đã đóng kết nối và tất cả đều hoạt động.
Charbel

12
Lưu ý bên: Nếu sử dụng Management Studio, việc đóng cửa sổ truy vấn sẽ đóng kết nối
Joe Phillips

3
@BradleyDotNET: vâng, chắc chắn
marc_s

2
Hãy nhớ rằng SQL Server Management Studio tự động cam kết nếu bạn đóng cửa sổ truy vấn / kết nối, theo mặc định.
Nuno

1
Lưu ý rằng khi máy khách đóng kết nối trong khi giao dịch đang hoạt động, nó không phải lúc nào cũng được khôi phục - điều này phụ thuộc vào máy khách và db. Ví dụ: khi một ứng dụng Java đóng kết nối với Oracle db, mọi kết nối đang mở sẽ được tự động cam kết.
AviD

38

Bạn thực sự có thể tự mình thử điều này, điều đó sẽ giúp bạn cảm nhận được cách hoạt động của nó.

Mở hai cửa sổ (tab) trong quản lý studio, mỗi cửa sổ sẽ có kết nối riêng với sql.

Bây giờ bạn có thể bắt đầu giao dịch trong một cửa sổ, thực hiện một số thao tác như chèn / cập nhật / xóa, nhưng chưa cam kết. thì trong cửa sổ khác, bạn có thể thấy cơ sở dữ liệu trông như thế nào từ bên ngoài giao dịch. Tùy thuộc vào mức độ cô lập, bảng có thể bị khóa cho đến khi cửa sổ đầu tiên được cam kết hoặc bạn có thể (không) xem giao dịch khác đã thực hiện những gì cho đến nay, v.v.

Chơi xung quanh các mức độ cách ly khác nhau và không có gợi ý khóa để xem chúng ảnh hưởng như thế nào đến kết quả.

Cũng xem điều gì sẽ xảy ra khi bạn gặp lỗi trong giao dịch.

Điều rất quan trọng là phải hiểu tất cả những thứ này hoạt động như thế nào nếu không bạn sẽ bị bối rối bởi những gì sql làm, nhiều lần.

Chúc vui vẻ! GJ.


được nhưng liệu giao dịch có được ghi vào nhật ký ít nhất trước khi phát hành cam kết không? Ví dụ: giả sử tôi muốn bắt đầu một giao dịch, hãy chạy lệnh chèn và "làm điều gì đó khác" trước khi thực hiện cam kết. lệnh chèn của tôi sẽ được viết để đăng nhập? theo cách đó nếu máy chủ bị treo trước khi thực hiện cam kết .. nó có thể trở lại vị trí cũ và tôi chỉ có thể phát hành cam kết sau (bất cứ khi nào tôi làm xong "việc khác").
user1870400

16

Các giao dịch nhằm mục đích chạy hoàn toàn hoặc không. Cách duy nhất để hoàn thành giao dịch là cam kết, bất kỳ cách nào khác sẽ dẫn đến việc hoàn trả.

Do đó, nếu bạn bắt đầu và sau đó không cam kết, nó sẽ được khôi phục khi đóng kết nối (vì giao dịch bị ngắt mà không được đánh dấu là hoàn thành).


Đó là cách nó phải như vậy, nhưng nó không phải luôn luôn như vậy.
FalcoGer

... chẳng hạn như MyISAM của mySQL , chắc chắn không hỗ trợ các giao dịch.
Piskvor rời tòa nhà vào

3

phụ thuộc vào mức độ cô lập của giao dịch nhập cảnh.

Giải thích sự cô lập giao dịch Sql


6
Hành vi của các giao dịch không phụ thuộc vào mức độ cô lập. Số lượng khóa chúng có thể gây ra.
marc_s

Tôi khá chắc chắn dữ liệu nào có thể được đọc bởi một kết nối chắc chắn phụ thuộc vào mức độ cách ly. Nếu bạn đặt cách ly thành READ UNCOMMITTED, bạn có thể đọc dữ liệu chưa được cam kết và trên thực tế có thể được khôi phục lại tại một số thời điểm theo dõi, nhưng điều này đảm bảo không có khóa. Nếu bạn đã READ COMMITTED làm mức cách ly, thì bạn không thể đọc các hàng không được cam kết - ứng dụng khách thứ hai sẽ bị treo trừ khi bạn sử dụng SNAPSHOT.
Xhalent

2

Khi bạn mở một giao dịch, không có gì bị khóa bởi chính nó. Nhưng nếu bạn thực hiện một số truy vấn bên trong giao dịch đó, tùy thuộc vào mức độ cô lập, một số hàng, bảng hoặc trang bị khóa, do đó nó sẽ ảnh hưởng đến các truy vấn khác cố gắng truy cập chúng từ các giao dịch khác.


1

Ví dụ cho Giao dịch

bắt đầu tran tt

Câu lệnh sql của bạn

nếu lỗi xảy ra rollback tran tt khác cam kết tran tt

Miễn là bạn chưa thực hiện commit tran tt, dữ liệu sẽ không bị thay đổi


1
Lưu ý rằng việc đặt tên cho các giao dịch không chỉ không cần thiết trong MS SQL mà nó có thể mang lại cảm giác kiểm soát sai. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Ykhông hoạt động, chẳng hạn. Xem stackoverflow.com/questions/1273376/…

0

Ngoài các vấn đề khóa tiềm ẩn mà bạn có thể gây ra, bạn cũng sẽ thấy rằng nhật ký giao dịch của mình bắt đầu phát triển vì chúng không thể bị cắt bớt quá LSN tối thiểu cho một giao dịch đang hoạt động và nếu bạn đang sử dụng cách ly ảnh chụp nhanh thì cửa hàng phiên bản của bạn trong tempdb sẽ phát triển cho lý do tương tự.

Bạn có thể sử dụng dbcc opentranđể xem chi tiết của giao dịch mở cũ nhất.


0

Bất kỳ giao dịch nào không được ghi chú sẽ khiến máy chủ bị khóa và các truy vấn khác sẽ không thực hiện trên máy chủ. Bạn cần khôi phục giao dịch hoặc cam kết giao dịch đó. Việc đóng SSMS cũng sẽ chấm dứt giao dịch, điều này sẽ cho phép các truy vấn khác thực hiện.


-4

Hành vi không được xác định, vì vậy bạn phải đặt rõ ràng một cam kết hoặc một lần khôi phục:

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

"Nếu chế độ cam kết tự động bị tắt và bạn đóng kết nối mà không cam kết rõ ràng hoặc khôi phục các thay đổi cuối cùng của mình, thì hoạt động COMMIT ngầm sẽ được thực thi."

Hsqldb thực hiện khôi phục

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

kết quả là

2011-11-14 14: 20: 22,519 THÔNG TIN chính [SqlAutoCommitExample: 55] [AutoCommit enable = false] 2011-11-14 14: 20: 22,546 THÔNG TIN chính [SqlAutoCommitExample: 65] [Đã tìm thấy 0 # người dùng trong cơ sở dữ liệu]


2
Điều này có thể đúng đối với Oracle (Tôi không có ý tưởng), nhưng hỏi được hỏi về MS-SQL
PaulG

Báo giá đầu tiên áp dụng cho trình điều khiển JDBC, không áp dụng cho máy chủ.
djechlin 17/09/13
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.