From 299b2621f7ff3efbf820bea1a12e8f1e7680d616 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Mon, 18 Oct 2010 15:50:06 -0700 Subject: [PATCH] Fix: Exceptions in commands do cancel transactions (same thing in background tasks) Components that control using() scope for work context will also indicate transaction cancelled when an exception passes out of that scope See http://orchard.codeplex.com/workitem/16604 --HG-- branch : dev extra : rebase_source : 2d53cdbea1e9dd7ceb022f781621b01bb1f95a87 --- src/Orchard/Commands/CommandHostAgent.cs | 14 +++++++++++++- src/Orchard/Tasks/SweepGenerator.cs | 18 +++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Orchard/Commands/CommandHostAgent.cs b/src/Orchard/Commands/CommandHostAgent.cs index 05799f2f1..ad19d8655 100644 --- a/src/Orchard/Commands/CommandHostAgent.cs +++ b/src/Orchard/Commands/CommandHostAgent.cs @@ -6,6 +6,7 @@ using System.Web.Mvc; using System.Web.Routing; using Autofac; using Orchard.Caching; +using Orchard.Data; using Orchard.Environment; using Orchard.Environment.Configuration; using Orchard.Environment.State; @@ -48,6 +49,8 @@ namespace Orchard.Commands { tenant = tenant ?? "Default"; using (var env = CreateStandaloneEnvironment(tenant)) { + var commandManager = env.Resolve(); + var transactionManager = env.Resolve(); var parameters = new CommandParameters { Arguments = args, @@ -56,7 +59,16 @@ namespace Orchard.Commands { Output = output }; - env.Resolve().Execute(parameters); + try { + commandManager.Execute(parameters); + } + catch { + // any database changes in this using(env) scope are invalidated + transactionManager.Cancel(); + + // exception handling performed below + throw; + } } // in effect "pump messages" see PostMessage circa 1980 diff --git a/src/Orchard/Tasks/SweepGenerator.cs b/src/Orchard/Tasks/SweepGenerator.cs index 627838b9a..bd1a25076 100644 --- a/src/Orchard/Tasks/SweepGenerator.cs +++ b/src/Orchard/Tasks/SweepGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Timers; using Autofac; +using Orchard.Data; using Orchard.Environment; using Orchard.Logging; @@ -57,9 +58,20 @@ namespace Orchard.Tasks { public void DoWork() { // makes an inner container, similar to the per-request container using (var scope = _workContextAccessor.CreateWorkContextScope()) { - // resolve the manager and invoke it - var manager = scope.Resolve(); - manager.Sweep(); + var transactionManager = scope.Resolve(); + + try { + // resolve the manager and invoke it + var manager = scope.Resolve(); + manager.Sweep(); + } + catch { + // any database changes in this using scope are invalidated + transactionManager.Cancel(); + + // pass exception along to actual handler + throw; + } } }