Skip to content

Instantly share code, notes, and snippets.

@ragnard
Created July 12, 2010 14:14
Show Gist options
  • Save ragnard/472508 to your computer and use it in GitHub Desktop.
Save ragnard/472508 to your computer and use it in GitHub Desktop.
using System.Messaging;
using System.Transactions;
using NHibernate.Criterion;
using NUnit.Framework;
using System.Collections;
namespace NHibernate.Test.NHSpecificTest.NH2238
{
[TestFixture]
public class Fixture : BugTestCase
{
public override string BugNumber
{
get { return "NH2238"; }
}
protected override IList Mappings
{
get { return new[] { "NHSpecificTest.NH2238.Person.hbm.xml" }; }
}
protected Person Alice { get; set; }
protected override void OnSetUp()
{
base.OnSetUp();
Alice = new Person { Name = "Alice" };
using(var session = OpenSession())
using(var tx = session.BeginTransaction())
{
session.Save(Alice);
tx.Commit();
}
}
protected override void OnTearDown()
{
using(ISession session = OpenSession())
using(ITransaction t = session.BeginTransaction())
{
session.Delete("from System.Object"); // clear everything from database
t.Commit();
}
base.OnTearDown();
}
[Test]
public void RenamePersonUsingITransaction()
{
using(var session = OpenSession())
using(var tx = session.BeginTransaction())
{
var alice = session.Load<Person>(Alice.Id);
alice.Name = "Bob";
session.Save(alice);
tx.Commit();
}
Assert.IsTrue(PersonExists("Bob"));
}
[Test]
public void RenamePersonUsingTransactionScope()
{
using(var session = OpenSession())
using(var scope = new TransactionScope())
{
var alice = session.Load<Person>(Alice.Id);
alice.Name = "Bob";
session.Save(alice);
scope.Complete();
}
Assert.IsTrue(PersonExists("Bob"));
}
[Test]
public void RenamePersonUsingPromotedTransactionScope()
{
var queue = CreateQueue();
using(var session = OpenSession())
using(var scope = new TransactionScope())
{
var alice = session.Load<Person>(Alice.Id);
alice.Name = "Bob";
session.Save(alice);
queue.Send("Alice was renamed to Bob", MessageQueueTransactionType.Automatic);
scope.Complete();
}
Assert.IsTrue(PersonExists("Bob"));
}
private bool PersonExists(string name)
{
bool exists;
using(var session = OpenSession())
using(var tx = session.BeginTransaction())
{
var criteria = session.CreateCriteria<Person>().Add(Restrictions.Eq("Name", name));
exists = criteria.UniqueResult<Person>() != null;
tx.Commit();
}
return exists;
}
private static MessageQueue CreateQueue()
{
const string queueName = @".\private$\nhibernatetest";
if(!MessageQueue.Exists(queueName))
{
MessageQueue.Create(queueName, true);
}
return new MessageQueue(queueName);
}
}
}
namespace NHibernate.Test.NHSpecificTest.NH2238
{
public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2238">
<class name="Person" table="person">
<id name="Id" column="PersonId" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" />
</class>
</hibernate-mapping>
16:12:30,668 ERROR AbstractSessionImpl:126 - DTC transaction prepre phase failed
System.InvalidOperationException: ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method)
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()
at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery() in D:\Projects\nhibernate\nhibernate\src\NHibernate\AdoNet\SqlClientSqlCommandSet.cs:line 117
at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps) in D:\Projects\nhibernate\nhibernate\src\NHibernate\AdoNet\SqlClientBatchingBatcher.cs:line 104
at NHibernate.AdoNet.AbstractBatcher.ExecuteBatchWithTiming(IDbCommand ps) in D:\Projects\nhibernate\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:line 426
at NHibernate.AdoNet.AbstractBatcher.ExecuteBatch() in D:\Projects\nhibernate\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:line 411
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in D:\Projects\nhibernate\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 116
at NHibernate.Engine.ActionQueue.ExecuteActions() in D:\Projects\nhibernate\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 147
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in D:\Projects\nhibernate\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 241
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in D:\Projects\nhibernate\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:line 19
at NHibernate.Impl.SessionImpl.Flush() in D:\Projects\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1524
at NHibernate.Transaction.AdoNetWithDistrubtedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) in D:\Projects\nhibernate\nhibernate\src\NHibernate\Transaction\AdoNetWithDistrubtedTransactionFactory.cs:line 115
System.InvalidOperationException : The operation is not valid for the current state of the enlistment.
at System.Transactions.EnlistmentState.InternalIndoubt(InternalEnlistment enlistment)
at System.Transactions.VolatileDemultiplexer.BroadcastInDoubt(ref VolatileEnlistmentSet volatiles)
at System.Transactions.TransactionStatePromotedIndoubt.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStatePromotedBase.InDoubtFromEnlistment(InternalTransaction tx)
at System.Transactions.DurableEnlistmentDelegated.InDoubt(InternalEnlistment enlistment, Exception e)
at System.Transactions.SinglePhaseEnlistment.InDoubt(Exception e)
at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
at System.Transactions.TransactionStateDelegatedCommitting.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStateDelegated.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
at NHibernate.Test.NHSpecificTest.NH42.Fixture.RenamePersonUsingPromotedTransactionScope() in Fixture.cs: line 101
System.InvalidOperationException: Operation is not valid due to the current state of the object.
at System.Transactions.TransactionState.ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
at System.Transactions.VolatileEnlistmentPreparing.ForceRollback(InternalEnlistment enlistment, Exception e)
at System.Transactions.PreparingEnlistment.ForceRollback(Exception e)
at NHibernate.Transaction.AdoNetWithDistrubtedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) in AdoNetWithDistrubtedTransactionFactory.cs: line 127
at System.Transactions.VolatileEnlistmentPreparing.EnterState(InternalEnlistment enlistment)
at System.Transactions.VolatileEnlistmentActive.ChangeStatePreparing(InternalEnlistment enlistment)
at System.Transactions.TransactionStatePromotedPhase0.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStatePromotedCommitting.ChangeStatePromotedPhase0(InternalTransaction tx)
at System.Transactions.Phase0VolatileDemultiplexer.InternalPrepare()
at System.Transactions.VolatileDemultiplexer.PoolablePrepare(Object state)
at System.Transactions.Phase0VolatileDemultiplexer.Prepare(IPromotedEnlistment en)
at System.Transactions.Oletx.OletxVolatileEnlistment.Prepare(OletxVolatileEnlistmentContainer container)
at System.Transactions.Oletx.OletxPhase0VolatileEnlistmentContainer.Phase0Request(Boolean abortHint)
at System.Transactions.Oletx.OletxTransactionManager.ShimNotificationCallback(Object state, Boolean timeout)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment