Okay, this is now fixed, have fun :-) On Mon, Jun 1, 2009 at 1:40 PM, Mike Nichols <[email protected]>wrote:
> Man thanks Ayende > > > > On Mon, Jun 1, 2009 at 10:13 AM, Ayende Rahien <[email protected]> wrote: > >> Yes, I can.You need to use IEnlistmentNotification impl and register that >> on the TX. >> I'll have a fix shortly >> >> >> On Mon, Jun 1, 2009 at 1:01 PM, Mike Nichols <[email protected]>wrote: >> >>> 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 -~----------~----~----~----~------~----~------~--~---
