2013-11-15 13 views
16

Được cấu hình với Trình phục vụ SQL Server: EF 6 kết thúc tốt đẹp mọi cuộc gọi thủ tục được lưu trữ duy nhất với BEGIN TRANCOMMIT TRAN.EF6 kết thúc tốt đẹp mọi lệnh gọi thủ tục được lưu trữ trong giao dịch của riêng nó. Làm thế nào để ngăn chặn điều này?

Nó không phải là một thay đổi phá vỡ?

Có lẽ nó không chỉ là một thay đổi phá vỡ, nhưng làm cho bất kỳ logic giao dịch không thể trong SPs như chúng ta bao giờ có thể rollback giao dịch của chúng tôi trong thủ tục lưu trữ sử dụng ROLLBACK TRAN (lưu ý: không có giao dịch lồng nhau trong SQL Server), vì vậy một rollback rollback để @@TRANCOUNT không. Khi chúng tôi tham gia giao dịch vì EF 6 chúng tôi nhận được "Số giao dịch sau EXECUTE cho biết số câu lệnh BEGIN và COMMIT không khớp. Số đếm trước = 1, số đếm hiện tại = 0" lỗi SQL Server chuẩn.

Vui lòng không hỏi tôi tại sao tôi muốn gọi các thủ tục được lưu trữ. Tôi có hàng trăm, và tất cả đều sử dụng logic TRY ... COMMIT ... CATCH ROLLBACK.

Bất kỳ ý tưởng nào về cách ngăn chặn EF 6 thực hiện việc này?

+0

Điều gì về việc sử dụng ['UseTransaction'] (http://msdn.microsoft.com/en-us/library/system.data.entity.database.usetransaction (v = vs.113) .aspx) và bắt đầu của riêng mình? –

+0

Điều gì về việc sử dụng ADO.Net trực tiếp nếu bạn muốn kiểm soát nhiều hơn? – Aron

Trả lời

23

Có một tình trạng quá tải của ExecuteSqlCommand phương pháp có thể ngăn chặn hành vi này:

db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sql, parameters); 
+0

Cảm ơn, Max bạn là tuyệt vời :-). Điều thú vị là các chuyên gia EF đã bỏ qua câu hỏi này trong hơn 2 tháng. (và bỏ qua thực tế rằng đây là một thay đổi phá vỡ) –

+0

Thông tin tiết kiệm cuộc sống - đã được tìm kiếm trong nhiều tuần! Cảm ơn! – eghetto

15

Trong EF 6.1.2, một lá cờ điều khiển hành vi. Đặt EnsureTransactionsForFunctionsAndCommands thành false sẽ ảnh hưởng đến các SP đã được nhập vào một thực thể (các lệnh gọi ExecuteFunction() bên trong).

using (SomeEf6Context ctx = NewContext()) 
{ 
    ctx.Configuration.EnsureTransactionsForFunctionsAndCommands = false; 
    // Call an imported SP 
}  

Cài đặt sẽ không ảnh hưởng đến bất kỳ cuộc gọi SaveChanges() nào.

MSDN Link

+0

Điều quan trọng là phải nhấn mạnh rằng bản sửa lỗi này yêu cầu bản cập nhật cho EF 6.1.2 hoặc mới hơn. Tôi đã chạy xung quanh tự hỏi tại sao tôi không thể tìm thấy tài sản EnsureTransactionsForFunctionsAndCommands trong gần một tuần vì tôi đã sử dụng EF 6.0.0. – Zachary

0

Như những gì crokusek nói, bạn có thể đặt lá cờ đó để vô hiệu hóa các giao dịch cho SPs.

Nếu bạn đang sử dụng bất kỳ dependency injection (DI) thư viện, bạn có thể thiết lập rằng như thế này (tôi đang sử dụng Injector Simple):

public partial class Startup 
{ 
    public Container ConfigureSimpleInjector(IAppBuilder app) 
    { 
     var container = new Container(); 

     // Configure OWIN and Identity Framework 
     ... 

     // Configure persistence 
     container.RegisterPerWebRequest<FakeDbContext>(() => 
     { 
      var fakeDbContext = new FakeDbContext(); 
      fakeDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false; 
      return fakeDbContext; 
     } 

     // Register other services 
     ... 

     container.Verify(); 

     // For MVC 
     DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 

     return container; 
    } 
} 
0

Chỉ cần đóng góp, tôi đang sử dụng Unity như DI, ​​EF 6.1.3 và cơ sở dữ liệu đầu tiên và tôi nhận được thông báo: "Giao dịch mới không được phép vì có các luồng khác chạy trong phiên" khi tôi gọi thủ tục hoặc hàm được ánh xạ trong tệp edmx của mình. Tùy chọn EnsureTransactionsForFunctionsAndCommands = false khắc phục sự cố. Giải pháp Max Zerbini cũng đã hoạt động, nhưng tôi sẽ sử dụng cách đó cho mỗi cuộc gọi thủ tục.

Các vấn đề liên quan