Chúng tôi đang trong quá trình thay thế dần mã truy cập dữ liệu cũ theo khung thực thể (4.3.1). Trong một số trường hợp, chúng tôi không thể tránh sử dụng cả hai cách truy cập dữ liệu trong một đơn vị công việc. Lý tưởng nhất, điều này nên được thực hiện trong một giao dịch. Tuy nhiên, mã cũ sử dụng SqlTransaction
s gọi Commit()
khi một đơn vị công việc được thực hiện và EF quản lý các giao dịch của riêng mình.Bỏ qua SqlTransaction.Commit trong TransactionScope
Vì vậy, chúng tôi đã nghĩ đến việc bao gồm mã "cũ" và "mới" trong một số TransactionScope
. Tuy nhiên, một Commit trong một xung quanh TransactionScope
luôn được thực hiện, ngay cả khi TransactionScope
không được hoàn thành. Đoạn mã này minh họa vấn đề của tôi:
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
using (var scope = new TransactionScope())
{
using (var tr = conn.BeginTransaction())
{
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tr;
cmd.CommandText = "some update statement";
cmd.ExecuteNonQuery();
}
tr.Commit();
}
// In reality the code above is part of a legacy DAL, immutable.
// (can't insert SaveChanges before tr.Commit).
context.SaveChanges();
if (<all ok>) // pseudo code for exception handling.
scope.Complete();
}
}
Các báo cáo cập nhật vẫn cam kết khi scope.Complete()
không phải là hit.
Vì vậy, có vẻ như tôi không thể sử dụng TransactionScope
để buộc mã truy cập dữ liệu cũ và SaveChanges
từ ngữ cảnh để thực thi trong một giao dịch. Hoặc có cách nào để ghi đè lên câu lệnh SqlTransaction.Commit?
Tôi biết rằng có nhiều bài đăng ở đây về TransactionScope và SqlTransaction, nhưng tất cả (đúng) nói rằng việc sử dụng SqlTransaction không cần thiết (cũng không được khuyến nghị) khi sử dụng TransactionScope. Nhưng không sử dụng SqlTransaction không phải là một tùy chọn ở đây. Chúng tôi có một khung kế thừa cam kết riêng của mình SqlTransaction
s và không có api để móc vào cơ chế giao dịch của nó.
Bạn ít nhất có quyền truy cập vào kết nối không? –
@LadislavMrnka Không, ngoài chuỗi kết nối trong tệp cấu hình. –