Làm cách nào để TransactionScope khôi phục các giao dịch?


99

Tôi đang viết một bài kiểm tra tích hợp trong đó tôi sẽ chèn một số đối tượng vào cơ sở dữ liệu và sau đó kiểm tra để đảm bảo phương pháp của tôi có truy xuất các đối tượng đó hay không.

Kết nối của tôi với cơ sở dữ liệu là thông qua NHibernate ... và phương pháp thông thường của tôi để tạo một bài kiểm tra như vậy là thực hiện như sau:

NHibernateSession.BeginTransaction();

//use nhibernate to insert objects into database
//retrieve objects via my method
//verify actual objects returned are the same as those inserted

NHibernateSession.RollbackTransaction();

Tuy nhiên, gần đây tôi đã tìm hiểu về TransactionScope có thể được sử dụng cho mục đích này ...

Một số mã ví dụ tôi đã tìm thấy như sau:

public static int AddDepartmentWithEmployees(Department dept)
{

    int res = 0;

    DepartmentAdapter deptAdapter = new DepartmentAdapter();
    EmployeeAdapter empAdapter = new EmployeeAdapter();
    using (TransactionScope txScope = new TransactionScope())
    {

        res += deptAdapter.Insert(dept.DepartmentName);
        //Custom method made to return Department ID 
        //after inserting the department "Identity Column"
        dept.DepartmentID = deptAdapter.GetInsertReturnValue();
        foreach(Employee emp in dept.Employees)
        {

            emp.EmployeeDeptID = dept.DepartmentID;
            res += empAdapter.Insert(emp.EmployeeName, emp.EmployeeDeptID);

        }
        txScope.Complete();

    }
    return res;

}

Tôi tin rằng nếu tôi không bao gồm dòng txScope.Complete(), dữ liệu được chèn vào sẽ được khôi phục lại. Nhưng tiếc là tôi không hiểu làm thế nào mà có thể ... làm thế nào để txScopeđối tượng giữ một ca khúc của deptAdapterempAdaptercác đối tượng và các giao dịch của họ trên cơ sở dữ liệu.

Tôi cảm thấy như mình đang thiếu một chút thông tin ở đây ... tôi có thực sự có thể thay thế các cuộc gọi BeginTransaction()RollbackTransaction() của mình bằng cách sử dụng mã của mình TransactionScopekhông?

Nếu không, thì làm thế nào TransactionScopeđể khôi phục các giao dịch?


Tôi chưa bao giờ sử dụng NHibernate, nhưng có lẽ liên kết này sẽ giúp bạn.

Nếu bạn đang tìm cách tốt hơn để quản lý các phiên NHibernate của mình để nhóm các hoạt động thành các giao dịch, bạn có thể muốn xem bài đăng trên blog của tôi về chủ đề đó dotnetchris.wordpress.com/2009/01/27/…
Chris Marisic

Câu trả lời:


107

Về cơ bản, TransactionScope không theo dõi Bộ điều hợp của bạn, điều nó làm là theo dõi các kết nối cơ sở dữ liệu. Khi bạn mở một kết nối DB, các kết nối sẽ xem liệu có giao dịch xung quanh không (Phạm vi giao dịch) và nếu có thì tranh thủ với nó. Thận trọng nếu có nhiều hơn một kết nối đến cùng một máy chủ SQL, điều này sẽ chuyển thành Giao dịch phân tán.

Điều gì xảy ra vì bạn đang sử dụng một khối đang sử dụng mà bạn đang đảm bảo việc xử lý sẽ được gọi ngay cả khi một ngoại lệ xảy ra. Vì vậy, nếu việc xử lý được gọi trước txScope.Complete (), TransactionScope sẽ yêu cầu các kết nối khôi phục lại các giao dịch của họ (hoặc DTC).


10
TransactionScope không theo dõi bất cứ thứ gì ngoài Giao dịch hiện tại trên luồng và sửa đổi nó nếu cần dựa trên mô hình (yêu cầu, yêu cầu mới, v.v., v.v.). Giao dịch chỉ đơn giản là thông báo bất cứ điều gì có liên quan đến nó, không chỉ các kết nối cơ sở dữ liệu.
casperOne

1
Tôi nghĩ điều này không hoàn toàn đúng. Tôi đã theo dõi một phần mã nguồn của TransactionScope và tôi cũng thấy msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx có nội dung "Nếu nó không tạo giao dịch, cam kết xảy ra bất cứ khi nào chủ sở hữu đối tượng committableTransaction gọi cam kết. Tại thời điểm đó, Trình quản lý giao dịch gọi người quản lý tài nguyên và thông báo cho họ cam kết hoặc quay lại, dựa trên việc liệu phương thức Hoàn thành có được gọi trên đối tượng TransactionScope hay không. " Dấu vết nguồn cũng chỉ ra hành vi này.
user44298

Tôi thấy điều này SO Q & A hữu ích: IEnlistmentNotification
mungflesh

Tôi vẫn chưa rõ ràng. Có vẻ như các đối tượng với các phương thức được gọi trong phạm vi giao dịch phải hợp tác với cơ chế Giao dịch. Họ phải tìm kiếm các thông báo Cam kết / Khôi phục bởi hệ thống và có thể tự khôi phục vì họ là những người thực hiện khôi phục khi được yêu cầu (nếu thực hiện xóa tệp, rõ ràng là chúng tôi không thể khôi phục một cách kỳ diệu trừ khi chúng tôi thực hiện một số biện pháp phòng ngừa). Có vẻ như hoạt động của máy chủ SQL là hợp tác. Nhưng có bất kỳ đối tượng hợp tác nào khác trong .Net không? Và làm thế nào để viết một lớp hợp tác? Tài liệu?
phút

54

Các TransactionScopelớp học làm việc với các Transactionlớp , đó là chủ đề cụ thể.

Khi TransactionScopeđược tạo, nó sẽ kiểm tra xem có một Transactioncho luồng không; nếu một cái tồn tại thì nó sử dụng cái đó, ngược lại, nó tạo một cái mới và đẩy nó lên ngăn xếp.

Nếu nó sử dụng một cái hiện có, thì nó chỉ tăng một bộ đếm cho các bản phát hành (vì bạn phải gọi Disposenó). Trong lần phát hành cuối cùng, nếu Transactionkhông được bắt đầu, nó sẽ quay trở lại tất cả công việc.

Đối với lý do tại sao các lớp dường như biết một cách kỳ diệu về các giao dịch, điều đó được để lại như một chi tiết triển khai cho những lớp muốn làm việc với mô hình này.

Khi bạn tạo của bạn deptAdapteremptAdaptertrường hợp, họ kiểm tra để xem nếu có một giao dịch hiện hành về các chủ đề (các tĩnh Currentbất động sản trên Transactionlớp). Nếu có, thì nó tự đăng ký với Transaction, để tham gia vào trình tự cam kết / khôi phục ( Transactionđiều khiển và có thể đề xuất cho các trình điều phối giao dịch khác nhau, chẳng hạn như hạt nhân, phân phối, v.v.).


4
Nó hoạt động như thế nào với (các) SqlConnection được tạo trong phạm vi? Lớp SqlConnection có sử dụng nội bộ lớp Giao dịch mà lần lượt sử dụng với TransactionScope không? Hay nó trực tiếp gia nhập TLS?
Kakira
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.