1
NHibernate在參與分佈式事務時拋出異常,並且通過指定自己的連接對象來打開會話。NHibernate - 分佈式事務和提供自己的連接導致異常
Unhandled Exception: System.InvalidOperationException: Disconnect cannot be call
ed while a transaction is in progress.
at NHibernate.AdoNet.ConnectionManager.Disconnect()
at NHibernate.Impl.SessionImpl.Close()
at NHibernate.Impl.SessionImpl.Dispose(Boolean isDisposing)
at NHibernate.Transaction.AdoNetWithDistrubtedTransactionFactory.<>c__Display
Class1.<EnlistInDistributedTransactionIfNeeded>b__0(Object sender, TransactionEv
entArgs e)
at System.Transactions.TransactionCompletedEventHandler.Invoke(Object sender,
TransactionEventArgs e)
at System.Transactions.TransactionStatePromotedCommitted.EnterState(InternalT
ransaction tx)
at System.Transactions.InternalTransaction.DistributedTransactionOutcome(Inte
rnalTransaction tx, TransactionStatus status)
at System.Transactions.Oletx.RealOletxTransaction.FireOutcome(TransactionStat
us statusArg)
at System.Transactions.Oletx.OutcomeEnlistment.InvokeOutcomeFunction(Transact
ionStatus status)
at System.Transactions.Oletx.OletxTransactionManager.ShimNotificationCallback
(Object state, Boolean timeout)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback
(Object state, Boolean timedOut)
以下代碼將重現該問題;參考當前的FluentNibernate和NHibernate 2.1.2.4000。
using System;
using System.Data.SqlClient;
using System.Transactions;
using FluentNHibernate.Mapping;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Cfg;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var cfg =
Fluently.Configure().Database(
MsSqlConfiguration.MsSql2008.ConnectionString("Integrated Security=SSPI;Data Source=.;Initial Catalog=Test").DefaultSchema("dbo")
).Mappings(x => x.FluentMappings.AddFromAssemblyOf<MyTableMap>()).BuildConfiguration();
using (var sf = cfg.BuildSessionFactory())
{
using (var ts = new TransactionScope().PromoteToDtc())
{
using (var conn = new SqlConnection("Integrated Security=SSPI;Data Source=.;Initial Catalog=Test"))
{
conn.Open();
using (var session = sf.OpenSession(conn))
{
session.Save(new MyTable { String = "Hello!" });
}
}
ts.Complete();
}
Console.WriteLine("It saved!");
Console.ReadLine();
}
}
}
public class DummyEnlistmentNotification : IEnlistmentNotification
{
public static readonly Guid Id = new Guid("E2D35055-4187-4ff5-82A1-F1F161A008D0");
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}
public void Commit(Enlistment enlistment)
{
enlistment.Done();
}
public void Rollback(Enlistment enlistment)
{
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
enlistment.Done();
}
}
public static class TSExetensions
{
public static TransactionScope PromoteToDtc(this TransactionScope scope)
{
Transaction.Current.EnlistDurable(DummyEnlistmentNotification.Id, new DummyEnlistmentNotification(), EnlistmentOptions.None);
return scope;
}
}
public class MyTable
{
public virtual int Id { get; private set; }
public virtual string String { get; set; }
}
public sealed class MyTableMap : ClassMap<MyTable>
{
public MyTableMap()
{
Id(x => x.Id).GeneratedBy.Native();
Map(x => x.String).Not.Nullable();
}
}
}
堆棧和異常表明您有一個分佈式事務仍在進行中。您的交易如何創建/管理? – 2010-11-19 15:08:38
我們沒有做任何事情,NServiceBus在調用我們的消息處理代碼之前和之後自動啓動並評論分佈式事務。 – Andy 2010-11-21 21:36:49