Are you able to test this without all the NH dependency cruft? I want to
keep hacking on this but can't figure out how to write a lighter test for it
to stick in RSB code base. Just throwing TransactionExceptions doesn't work

On Mon, Jun 1, 2009 at 8:12 AM, Ayende Rahien <[email protected]> wrote:

> Sigh,
> I reproduced the issue, not fun.
>
>
> On Mon, Jun 1, 2009 at 1:29 PM, Mike Nichols <[email protected]>wrote:
>
>>
>> I think I have narrowed the problem to transaction commit failures
>> that take place AFTER the 'Consume' invocation is made (ie in
>> MessageCompleted). These exceptions are outside the scope of the
>> try...catch wrapping the ProcessMessage call.
>> In the code I have above the transaction tries to commit (in ATM) and
>> then rolls back since SQL Server throws, aborting the transaction.
>> When the TransactionScope attempts to Dispose in RQTransport
>> ReceiveMessage method, the InternalTransaction throws since it was
>> aborted, making the whole app crash since it is unhandled.
>>
>> Any ideas on this? My attempts to handle TransactionException have so
>> far just thrown RSB into a loop.
>>
>> On May 30, 11:41 pm, Mike Nichols <[email protected]> wrote:
>> > I have a test case here that demonstrates the problem. I changed
>> > RQTransport on ReceiveMessage to catch TransactionAbortedException and
>> > Debugger.Launch inside the catch statement.
>> > Note this test is 'heavy' intentionally . RSB tries 5 times to handle
>> > the message but when the Session flushes the transaction aborts and
>> > since the transaction reference is outside the try...catch in
>> > ReceiveMessage it goes unhandled.
>> >
>> > First here is output from NHProf Error logging:
>> > It seems like since the exception is thrown inside the
>> > TransactionScope (tx) instead the inner try..catch is ignored and
>> > hence the TransactionAbortedException goes unhandled in the app,
>> > stopping it altogether.
>> >
>> > ERROR:
>> > DTC transaction prepre phase failed
>> > System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be
>> > between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
>> >    at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value)
>> >    at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value)
>> >    at System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime,
>> > Byte cb)
>> >    at System.Data.SqlClient.TdsParser.WriteValue(Object value,
>> > MetaType type, Byte scale, Int32 actualLength, Int32 encodingByteSize,
>> > Int32 offset, TdsParserStateObject stateObj)
>> >    at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[]
>> > rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest
>> > notificationRequest, TdsParserStateObject stateObj, Boolean
>> > isCommandProc)
>> >    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds
>> > (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean
>> > returnStream, Boolean async)
>> >    at System.Data.SqlClient.SqlCommand.RunExecuteReader
>> > (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean
>> > returnStream, String method, DbAsyncResult result)
>> >    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery
>> > (DbAsyncResult result, String methodName, Boolean sendToPipe)
>> >    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
>> >    at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand
>> > cmd)
>> >    at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation
>> > expectation)
>> >    at NHibernate.Persister.Entity.AbstractEntityPersister.Insert
>> > (Object id, Object[] fields, Boolean[] notNull, Int32 j,
>> > SqlCommandInfo sql, Object obj, ISessionImplementor session)
>> >    at NHibernate.Persister.Entity.AbstractEntityPersister.Insert
>> > (Object id, Object[] fields, Object obj, ISessionImplementor session)
>> >    at NHibernate.Action.EntityInsertAction.Execute()
>> >    at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
>> >    at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
>> >    at NHibernate.Engine.ActionQueue.ExecuteActions()
>> >    at
>> > NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions
>> > (IEventSource session)
>> >    at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush
>> > (FlushEvent event)
>> >    at NHibernate.Impl.SessionImpl.Flush()
>> >    at
>> >
>> NHibernate.Impl.AbstractSessionImpl.System.Transactions.IEnlistmentNotification.Prepare
>> > (PreparingEnlistment preparingEnlistment)
>> >
>> > TEST
>> >
>> ==============================================================================
>> > I am attaching it here in the Files section to make it easier to read,
>> > too:
>> >
>> > namespace Cei.MaterialsTesting.Bugs
>> > {
>> >         public class RSBBugs :
>> > OccasionalConsumerOf<RSBBugs.ConsumerCompleteMessage>
>> >         {
>> >                 private WindsorContainer container;
>> >                 private ManualResetEvent wait;
>> >
>> >                 public RSBBugs()
>> >                 {
>> >                         container = new WindsorContainer(new
>> XmlInterpreter("Bugs/
>> > RSBBugs.config"));
>> >                         container.AddFacility("rhino.esb", new
>> RhinoServiceBusFacility
>> > ().AddMessageModule<UnitOfWorkMessageModule>());
>> >                         container.AddFacility("trx", new
>> RhinoTransactionFacility());
>> >                         container.AddFacility("nh_uow", new
>> NHibernateUnitOfWorkFacility(
>> >                                                                 new
>> > NHibernateUnitOfWorkFacilityConfig(
>> >
>> Assembly.GetAssembly(typeof
>> > (BadDateEntity)))));
>> >                         container.AddComponent<SQLMessageConsumer>();
>> >
>> >                         var cfg = new Configuration()
>> >
>> .SetProperty(Environment.ReleaseConnections, "on_close")
>> >                                 .SetProperty(Environment.Dialect,
>> > "NHibernate.Dialect.MsSql2005Dialect")
>> >
>> .SetProperty(Environment.ConnectionDriver,
>> > "NHibernate.Driver.SqlClientDriver")
>> >
>> .SetProperty(Environment.ConnectionString,  string.Format("Server=
>> > (local);initial catalog={0};Integrated Security=SSPI",
>> > "MaterialsTesting_Test"))
>> >
>> .SetProperty(Environment.ProxyFactoryFactoryClass, typeof
>> > (ProxyFactoryFactory).AssemblyQualifiedName)
>> >                                 .SetProperty(Environment.ShowSql,
>> "true")
>> >                                 .SetProperty(Environment.BatchSize,
>> "10")
>> >
>> .SetProperty(Environment.GenerateStatistics, "true");
>> >
>> >                         cfg.AddXmlFile("Bugs/BadDateEntity.hbm.xml");
>> >
>> >                         SessionFactory = cfg.BuildSessionFactory();
>> >                         using (var session =
>> SessionFactory.OpenSession())
>> >                         {
>> >                                 new SchemaExport(cfg).Execute(false,
>> true, false,
>> > session.Connection, null);
>> >                         }
>> >                         IoC.Initialize(container);
>> >                 }
>> >
>> >                 protected ISessionFactory SessionFactory { get; set; }
>> >
>> >                 [Observation]
>> >                 public void should_throw()
>> >                 {
>> >                         using(var bus =
>> container.Resolve<IStartableServiceBus>())
>> >                         {
>> >                                 bus.Start();
>> >                                 using(bus.AddInstanceSubscription(this))
>> >                                 {
>> >                                         wait = new
>> ManualResetEvent(false);
>> >                                         bus.Send(new SQLMessage());
>> >
>> Assert.True(wait.WaitOne(TimeSpan.FromSeconds(60),false));
>> >                                 }
>> >                         }
>> >                 }
>> >                 public class SQLMessage
>> >                 {
>> >
>> >                 }
>> >
>> >                 [Transactional]
>> >                 public class SQLMessageConsumer : ConsumerOf<SQLMessage>
>> >                 {
>> >                         private IServiceBus bus;
>> >
>> >                         public SQLMessageConsumer(IServiceBus bus)
>> >                         {
>> >                                 this.bus = bus;
>> >                         }
>> >
>> >                         [Transaction]
>> >                         public void Consume(SQLMessage message)
>> >                         {
>> >
>> >                                 var bad = new BadDateEntity {CreatedOn =
>> DateTime.MinValue};
>> >                                 UnitOfWork.CurrentSession.Save(bad);
>> >                                 bus.Publish(new
>> ConsumerCompleteMessage());
>> >                         }
>> >                 }
>> >                 public class ConsumerCompleteMessage
>> >                 {
>> >                 }
>> >
>> >                 public void Consume(ConsumerCompleteMessage message)
>> >                 {
>> >                         wait.Set();
>> >                 }
>> >         }
>> >
>> > }
>>
>>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to