public void Release(Scope scope, bool valid) { switch (Mode) { case PoolMode.None: Queries.EndQuery(scope.Query, valid); scope.Factory.Dispose(); break; default: if (valid && !scope.Query.InTransaction && Scopes.Count < Size) { Scopes.Add(scope); } else { Queries.EndQuery(scope.Query, valid); scope.Factory.Dispose(); if (Scopes.Count < Size) { Scopes.Add(SetupReadonlyScope()); } } break; } }
/// <summary> /// Rollback started transaction. /// </summary> /// <param name="manager">query manager</param> /// <param name="query">ADO.NET driver</param> public static void Rollback(this IDatabaseQueryManager manager, IDatabaseQuery query) { Contract.Requires(manager != null); Contract.Requires(query != null); if (!query.InTransaction) { throw new ArgumentException("Only queries in transaction can be rollbacked"); } manager.EndQuery(query, false); }
public IProcessingResult <TOutput> Execute <TInput, TOutput>(IServerCommandDescription <TInput>[] commandDescriptions) { if (commandDescriptions == null || commandDescriptions.Length == 0) { return (ProcessingResult <TOutput> .Create( "There are no commands to execute.", HttpStatusCode.BadRequest, null, 0)); } var stopwatch = Stopwatch.StartNew(); foreach (var c in commandDescriptions) { if (!Permissions.CanAccess(c.CommandType)) { Logger.Trace( () => "Access denied. User: {0}. Target: {1}.".With( Thread.CurrentPrincipal.Identity.Name, c.CommandType.FullName)); return (ProcessingResult <TOutput> .Create( "You don't have permission to execute command: " + c.CommandType.FullName, HttpStatusCode.Forbidden, null, stopwatch.ElapsedMilliseconds)); } } var inputSerializer = GetSerializer <TInput>(); var outputSerializer = GetSerializer <TOutput>(); var commands = new CommandInfo <TInput> [commandDescriptions.Length]; var useTransaction = false; for (int i = 0; i < commands.Length; i++) { var c = commands[i] = new CommandInfo <TInput>(commandDescriptions[i], ActualCommands); useTransaction = useTransaction || !c.IsReadOnly; if (c.Target == null) { Logger.Trace( () => "Unknown target. User: {0}. Target: {1}.".With( Thread.CurrentPrincipal.Identity.Name, commandDescriptions[i].CommandType.FullName)); return (ProcessingResult <TOutput> .Create( "Unknown command: {0}. Check if requested command is registered in the system".With( c.Description.CommandType), HttpStatusCode.BadRequest, null, stopwatch.ElapsedMilliseconds)); } } var scopeID = useTransaction ? Guid.NewGuid().ToString() : null; using (var scope = ObjectFactory.CreateScope(scopeID)) { var executedCommands = new List <ICommandResultDescription <TOutput> >(commandDescriptions.Length); IDatabaseQuery query = null; try { try { query = TransactionManager.StartQuery(useTransaction); } catch (Exception ex) { Logger.Error("Can't start query. Error: " + ex.ToString()); return(Exceptions.DebugMode ? ProcessingResult <TOutput> .Create( ex.ToString(), HttpStatusCode.ServiceUnavailable, null, stopwatch.ElapsedMilliseconds) : ProcessingResult <TOutput> .Create( "Unable to create database connection", HttpStatusCode.ServiceUnavailable, null, stopwatch.ElapsedMilliseconds)); } scope.RegisterInstance(query); if (useTransaction) { scope.RegisterInstance <IEnumerable <IServerCommandDescription <TInput> > >(commandDescriptions); scope.RegisterInstance <IEnumerable <ICommandResultDescription <TOutput> > >(executedCommands); scope.RegisterType(typeof(ProcessingContext), typeof(IProcessingEngine), InstanceScope.Singleton); } foreach (var cmd in commands) { var result = cmd.GetCommand(scope).Execute(inputSerializer, outputSerializer, cmd.Description.Data); if (result == null) { throw new FrameworkException("Result returned null for " + cmd.Target.FullName); } executedCommands.Add(CommandResultDescription <TOutput> .Create(cmd.Description.RequestID, result)); if ((int)result.Status >= 400) { TransactionManager.EndQuery(query, false); return(ProcessingResult <TOutput> .Create( result.Message, result.Status, executedCommands, stopwatch.ElapsedMilliseconds)); } } TransactionManager.EndQuery(query, true); return (ProcessingResult <TOutput> .Create( "Commands executed in: " + stopwatch.ElapsedMilliseconds.ToString() + " ms.", HttpStatusCode.OK, executedCommands, stopwatch.ElapsedMilliseconds)); } catch (SecurityException ex) { Logger.Trace( () => "Security error. User: {0}. Error: {1}.".With( Thread.CurrentPrincipal.Identity.Name, ex.ToString())); TransactionManager.EndQuery(query, false); return (ProcessingResult <TOutput> .Create( "You don't have authorization to perform requested action: " + ex.Message, HttpStatusCode.Forbidden, executedCommands, stopwatch.ElapsedMilliseconds)); } catch (AggregateException ex) { Logger.Trace( () => "Multiple errors. User: {0}. Error: {1}.".With( Thread.CurrentPrincipal.Identity.Name, ex.GetDetailedExplanation())); TransactionManager.EndQuery(query, false); return(Exceptions.DebugMode ? ProcessingResult <TOutput> .Create( ex.GetDetailedExplanation(), HttpStatusCode.InternalServerError, executedCommands, stopwatch.ElapsedMilliseconds) : ProcessingResult <TOutput> .Create( string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)), HttpStatusCode.InternalServerError, executedCommands, stopwatch.ElapsedMilliseconds)); } catch (OutOfMemoryException ex) { Logger.Error("Out of memory error. Error: " + ex.GetDetailedExplanation()); TransactionManager.EndQuery(query, false); return(Exceptions.DebugMode ? ProcessingResult <TOutput> .Create( ex.GetDetailedExplanation(), HttpStatusCode.ServiceUnavailable, executedCommands, stopwatch.ElapsedMilliseconds) : ProcessingResult <TOutput> .Create( ex.Message, HttpStatusCode.ServiceUnavailable, executedCommands, stopwatch.ElapsedMilliseconds)); } catch (Exception ex) { Logger.Trace( () => "Unexpected error. User: {0}. Error: {1}.".With( Thread.CurrentPrincipal.Identity.Name, ex.GetDetailedExplanation())); TransactionManager.EndQuery(query, false); return(Exceptions.DebugMode ? ProcessingResult <TOutput> .Create( ex.GetDetailedExplanation(), HttpStatusCode.InternalServerError, executedCommands, stopwatch.ElapsedMilliseconds) : ProcessingResult <TOutput> .Create( ex.Message, HttpStatusCode.InternalServerError, executedCommands, stopwatch.ElapsedMilliseconds)); } } }