Câu lệnh using sẽ khôi phục một giao dịch cơ sở dữ liệu nếu xảy ra lỗi?


83

Tôi có một IDbTransaction trong một câu lệnh using nhưng tôi không chắc liệu nó có được khôi phục hay không nếu một ngoại lệ được đưa ra trong một câu lệnh using. Tôi biết rằng một câu lệnh using sẽ thực thi việc gọi Dispose () ... nhưng có ai biết điều đó có đúng với Rollback () không?

Cập nhật: Ngoài ra, tôi có cần gọi commit () một cách rõ ràng như tôi có bên dưới hay điều đó cũng sẽ được xử lý bởi câu lệnh using?

Mã của tôi trông giống như sau:

using Microsoft.Practices.EnterpriseLibrary.Data;

...

using(IDbConnection connection = DatabaseInstance.CreateConnection())
{
    connection.Open();

    using(IDbTransaction transaction = connection.BeginTransaction())
    {
       //Attempt to do stuff in the database
       //potentially throw an exception
       transaction.Commit();
    }
}

3
Xin chào, chỉ để làm rõ trường hợp "cam kết". Tất nhiên là bắt buộc bởi vì using () {} chỉ gọi phương thức Dispose (). Lớp Transaction.Dispose không thể biết nếu nó nên Commit hoặc Vứt bỏ nếu cũng cam kết là tự động :)
Manitra Andriamitondra

Câu trả lời:


104

Phương thức Dispose cho lớp giao dịch thực hiện một lần quay lui trong khi lớp của Oracle thì không. Vì vậy, từ quan điểm của giao dịch, nó phụ thuộc vào việc thực hiện.

Mặt khác, usingcâu lệnh cho đối tượng kết nối sẽ đóng kết nối với cơ sở dữ liệu hoặc trả kết nối về nhóm sau khi đặt lại nó. Trong cả hai trường hợp, các giao dịch chưa thanh toán nên được hoàn trả. Đó là lý do tại sao một ngoại lệ không bao giờ để lại một giao dịch đang hoạt động.

Ngoài ra, có, bạn nên gọi Commit()một cách rõ ràng.


Nó sẽ, tôi thậm chí đã thử nghiệm điều này một lần bằng cách ném ra một ngoại lệ.
Pawel Krakowiak

1
Đó tuyệt vời, nhưng nó làm việc cho triển khai khác của IDbTransaction nếu bạn đang sử dụng nó để tương thích chéo db?
Matt Hamilton

4
@mezoid: Cam kết sẽ không bao giờ tự động xảy ra. @matt: Họ nên, theo thiết kế.
Sedat Kapanoglu

1
@MattHamilton đúng như ssg đã nói. Tôi đã kiểm tra nguồn kết nối .net của MySQL, họ cũng làm tương tự như được hiển thị ở trên. Rollbackđược gọi vào Dispose! :)
nawfal

1
Nếu bạn đang sử dụng a System.Data.OracleConnection, nó sẽ không khôi phục khi xử lý. Hoặc ít nhất, đối với chúng tôi thì không.
Medinoc

20

Bạn phải gọi cam kết. Câu lệnh using sẽ không cam kết bất cứ điều gì cho bạn.


5
Có, việc sử dụng sẽ gọi Dispose khi thoát, sẽ gọi Rollback, không phải commit.
kinh ngạc

4

Tôi tin rằng nếu có một ngoại lệ Commit()không bao giờ được gọi, thì giao dịch sẽ tự động quay trở lại.


Vâng, đó là sự hiểu biết của tôi. Một giao dịch tồn tại cho đến khi một cam kết được gọi hoặc kết nối kết thúc. Tại thời điểm đó, nhật ký giao dịch thực sự được cập nhật với các thay đổi hoặc được khôi phục trong trường hợp kết nối bị đóng (bạn biết rằng bạn sẽ không bao giờ nhận được cam kết ra khỏi kết nối đã đóng;)).
Mike
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.