Tôi hiện đang cố gắng sử dụng phạm vi giao dịch lồng nhau để truy cập DB dựa vào Cơ sở dữ liệu SQL Azure.Cách sử dụng lồng ghép giao dịch lồng nhau đối với cơ sở dữ liệu SQL Azure
Tôi đang sử dụng đoạn mã sau (Net 4.5.1, mã của tôi là async tất cả các con đường xuống, nó ASP.Net MVC với EF6.1):
public async Task Test()
{
// In my actual code, the DbContext is injected within the constructor
// of my ASP.Net MVC Controller (thanks to IoC and dependency injection)
// The same DbContext instance is used for the whole HttpRequest
var context = new TestContext();
using (var t1 = StartTransactionForAsync())
{
using (var t2 = StartTransactionForAsync())
{
context.Users.Add(new User { Name = Guid.NewGuid().ToString() });
await context.SaveChangesAsync();
t2.Complete();
}
... // Some more code here
t1.Complete();
}
}
private static TransactionScope StartTransactionForAsync()
{
return new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },
TransactionScopeAsyncFlowOption.Enabled);
}
Mọi thứ đều tốt, ngoại trừ đôi khi các TransactionScope
đang leo thang để MSDTC đó là (rõ ràng) không được hỗ trợ bởi cơ sở dữ liệu SQL Azure. Vì vậy, đôi khi tôi nhận được lỗi sau:
Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
tôi có thể thêm Enlist=False
đến chuỗi kết nối của tôi, nhưng nó sẽ phá vỡ các mã trên, như giao dịch nội vẫn sẽ chèn vào cơ sở dữ liệu ngay cả khi ngoài TransactionScope
được xử lý mà không cần Complete
.
Tôi đang nhắm mục tiêu một Cơ sở dữ liệu đơn, sử dụng một đơn Entity Framework bối cảnh cho tôi toàn bộ HttpRequest
, luôn với cùng chuỗi kết nối.
Vì vậy, câu hỏi của tôi là: giao dịch
- được lồng nhau được hỗ trợ bởi cơ sở dữ liệu SQL Azure ở tất cả?
- tại sao mã trên đôi khi leo thang lên MSDTC?
Các official documentation nói:
Microsoft Azure SQL Database does not support distributed transactions, which are transactions that affect several resources. For more information, see Distributed Transactions (ADO.NET).
Starting with the version 2.0, application transactions may be automatically promoted to distributed transactions. This applies to applications that use the System.Data.SqlClient class to perform database operations in the context of a System.Transactions transaction.
Transaction promotion occurs when you open multiple connections to different servers or databases within a TransactionScope, or when you enlist multiple connections in a System.Transactions object by using the EnlistTransaction method. Transaction promotion also occurs when you open multiple concurrent connections to the same server and database either within the same TransactionScope or by using the EnlistTransaction method.
Starting with the version 3.5, the transaction will not be promoted if the connection strings for the concurrent connections are exactly the same. For more information about transactions and avoiding transaction promotion, see System.Transactions Integration with SQL Server (ADO.NET).
mà không trả lời bất cứ câu hỏi của tôi.
TransactionScope được phát minh cho giao dịch * ngầm/tự động * (tận dụng dịch vụ MSDTC), không dành cho giao dịch * lồng nhau *. Có vẻ như bạn đang bối rối những thuật ngữ đó.Chuyển đến DTC có thể xảy ra bởi vì bạn có một số công cụ async (có nghĩa là các luồng khác nhau, có thể có nghĩa là các kết nối khác nhau). Tôi hầu như không thấy lý do tại sao bạn muốn đặt công cụ async trong loại (máy chủ?) Mã - vượt ra ngoài thời trang hiện tại xung quanh "async" :-). Thêm thông tin về leo thang tại đây: http://stackoverflow.com/questions/1690892/transactionscope-automatically-escalating-to-msdtc-on-some-machines –
@SimonMourier Tôi không chắc tôi hiểu câu đầu tiên của bạn; 'TransactionScope' chắc chắn hỗ trợ các giao dịch lồng nhau (xem ví dụ http://stackoverflow.com/a/2742025/870604). Rollbacking phạm vi gốc nên rollback toàn bộ hoạt động. Đối với các công cụ async, tôi đang sử dụng nó vì lý do khả năng mở rộng/hiệu suất. Điều đó nói rằng, nó không thay đổi thực tế là ngay cả khi hai hoạt động được thực thi trên hai luồng khác nhau, chúng vẫn sử dụng cùng một kết nối DB (một cá thể DbContext duy nhất được sử dụng). – ken2k
Tôi chưa bao giờ nói TS không hỗ trợ các giao dịch lồng nhau. Tôi nói rằng bạn đang bối rối cả hai khái niệm. Giao dịch lồng nhau tồn tại lâu trước khi DTC tồn tại. Bạn có thể thực hiện giao dịch lồng nhau w/o TS, nhưng bạn đang nói về * phạm vi lồng nhau *. Async sẽ không mang lại bất kỳ lợi ích khả năng mở rộng nào ở đây, nếu đằng sau hiện trường, bạn đang sắp xếp trên một kết nối duy nhất (thực tế có thể tệ hơn), mà tôi vẫn còn nghi ngờ. IMHO bạn nên hiển thị một mã repro đầy đủ để tránh đoán hoang dã. –