2011-02-08 6 views
5

Tôi nhận được ngoại lệ sau khi sử dụng các hoạt động Nhibernate và ADO.Net bên trong giao dịch Scope.Eg. Đó là tốt với Nhibernate 2,1 nhưng bây giờ nâng cấp lên 3,0 mà ném lỗi.Nhibernate with TransactionScope Error - Giai đoạn chuẩn bị giao dịch DTC thất bại - Nâng cấp lên Nhibernate 3.0

using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
{ 
     GetmemberId(); --> NHibernate Call 
     Update(); ADO Call OracleDB 
} 

Vì đây hoạt động giao dịch như môi trường xung quanh, Nhibernate cố gắng để xử lý các giao dịch sớm trước khi giao dịch bên ngoài completes.correct tôi nếu tôi sai, Có giải pháp nào vì giúp tôi, nhưng khi tôi chuyển cuộc gọi Nhibernate ngoài TransactionScope tất cả mọi thứ hoạt động tốt. Ví dụ tôi đã đưa ra là mẫu một, mỏ liên quan đến một mẫu phức tạp hơn, vì tôi đã giữ cả hai cuộc gọi bên trong TransactionScope và lỗi Iam nhận được như sau,

ERROR 13 NHibernate.Impl.AbstractSessionImpl - DTC transaction prepre pha không thành công System.ObjectDisposedException: Không thể truy cập đối tượng được phân phối . Tên đối tượng: 'Giao dịch'. tại System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) tại System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) tại System.Transactions.TransactionScope.PushScope()
tại System.Transactions.TransactionScope.Initialize (Transaction transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) tại System.Transactions.TransactionScope..ctor (Transaction transactionToUse) tại NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (PreparingEnlistment preparingEnlistment) 2011-02- 08 13: 41: 46,033 L ERI 13 NHibernate.Impl.AbstractSessionImpl - Giai đoạn chuẩn bị giao dịch DTC không thành công System.ObjectDisposedException: Không thể truy cập đối tượng được phân phối . Tên đối tượng: 'Giao dịch'. tại System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) tại System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) tại System.Transactions.TransactionScope.PushScope()
tại System.Transactions.TransactionScope.Initialize (Transaction transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) tại System.Transactions.TransactionScope..ctor (Transaction transactionToUse) tại NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (preparingEnlistment preparingEnlistment)

012.351.

Trả lời

6

Hãy thử

Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")

Hoặc trong cấu hình nhibernate

<property name="transaction.factory_class"> 
NHibernate.Transaction.AdoNetTransactionFactory 
</property> 

Nó làm việc cho tôi =)

+0

Cảm ơn bạn! Nó làm việc cho tôi quá! – Saxophonist

1

Chúng tôi đã gặp lỗi này giống nhau, và nó được gây ra bằng cách này chúng tôi đã sử dụng các phiên và giao dịch trong Api Web của chúng tôi với NHibernate.

Chúng tôi nên đang sử dụng phiên cho mỗi yêu cầu. (Điều này có thể là một yêu cầu web hoặc thực hiện một trình xử lý NServiceBus.) Khi một yêu cầu bắt đầu, bạn nên mở một phiên và bắt đầu một giao dịch.

Chúng tôi đã không làm điều đó. Trong kho của chúng tôi, chúng tôi đã tạo phiên mới và giao dịch cho mọi yêu cầu cơ sở dữ liệu. Điều này có nghĩa là thay vì có một phiên/giao dịch duy nhất cho một yêu cầu, chúng tôi có nhiều yêu cầu.

Nguyên nhân gốc của lỗi cho chúng tôi là chúng tôi đang tải một thực thể (đối tượng mô hình miền) trong một phiên, sửa đổi và lưu nó bằng một phiên khác. Khi NHibernate thực hiện cuộc gọi cập nhật, phiên tải/giao dịch đã được cam kết, xóa và đóng.

Giải pháp là kéo phiên/phiên giao dịch của chúng tôi ra khỏi kho và lên đến lớp Bộ điều khiển (có thể thực hiện bằng HttpModule cho các cuộc gọi REST và/hoặc với lập trình hướng khía cạnh sử dụng tiêm phụ thuộc). Điều này một phiên/giao dịch sau đó sống cho cuộc đời của cuộc gọi REST hoặc thực hiện xử lý NServiceBus và được sử dụng cho tất cả các truy cập cơ sở dữ liệu trong suốt cuộc gọi đó. Khi cuộc gọi đó kết thúc, cuộc gọi đó sẽ được thực hiện hoặc quay lại khi thích hợp.

Câu trả lời được đưa ra ở trên thiết lập thuộc tính cấu hình chỉ đơn giản là tắt DTC và hoàn nguyên về cách thực hiện giao dịch NHibernate cũ hơn. Điều đó có thể giải quyết vấn đề cho bạn nếu bạn không bao giờ phải mở rộng quy mô Web Api của bạn lên nhiều trường hợp, nhưng nếu bạn làm như vậy, điều này sẽ gây ra vấn đề cho bạn.