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