here is my code:
var mainQuery = (IQueryable<dynamic>)SortedAndPaged().Select(selector);
var aggregateQuery = Aggregate();
FutureScalar<dynamic> futureAggregate;
dynamic[] futureMain;
try
{
futureAggregate = Query.ExecuteFutureScalar(key, () => aggregateQuery.FirstOrDefault());
futureMain = mainQuery.ToArray();
}
catch (StorageException e)
{
if (e.InnerException != null && typeof(SqlException) == e.InnerException.GetType() && e.InnerException.Message.Contains("Arithmetic overflow error"))
{
success = false;
message = "Ошибка аггрегирования";
Session.Current.Persist();
AggregateInfo.Clear();
futureAggregate = Query.ExecuteFutureScalar(key, () => aggregateQuery.FirstOrDefault());
futureMain = mainQuery.ToArray();
}
else
{
throw;
}
}
I try to execute two queries in one batch, one for tabular data, another - for Summary (aggregates)
and if I catch overflow exception - exclude this aggregates, and try to execute it one more time, but:
There is already an open DataReader associated with this Command which must be closed first.
[InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.]
System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5008639
System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +23
System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +144
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +87
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
System.Data.Common.DbCommand.ExecuteReader() +12
Xtensive.Storage.Providers.Sql.Driver.ExecuteReader(Session session, DbCommand command) +46
[StorageException: Error 'Unknown' while executing query 'SELECT TOP 1 [a].[column1], ...'. Original message: There is already an open DataReader associated with this Command which must be closed first.]
Xtensive.Storage.Providers.Sql.Driver.ExecuteReader(Session session, DbCommand command) +81
Xtensive.Storage.Providers.Sql.BatchingCommandProcessor.ExecuteBatch(Int32 numberOfTasks, QueryRequest lastRequest) +282
Xtensive.Storage.Providers.Sql.BatchingCommandProcessor.ExecuteRequestsWithReader(QueryRequest request) +50
Xtensive.Storage.Providers.Sql.ExecuteTupleReader>d__1.MoveNext() +121
Xtensive.Storage.Providers.Sql.<OnEnumerate>d__0.MoveNext() +151
Xtensive.Storage.Rse.Providers.<GetEnumerator>d__0.MoveNext() +206
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +327
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
Xtensive.Storage.Rse.<GetEnumerator>d__4.MoveNext() +219
System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +87
Xtensive.Core.<Batch>d__20`1.MoveNext() +194
Xtensive.Core.<ApplyBeforeAndAfter>d__28`1.MoveNext() +154
Xtensive.Storage.<ToTransactional>d__0`1.MoveNext() +193
System.Linq.<SelectManyIterator>d__14`2.MoveNext() +399
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +78
Werp.Controller.Services.GridReadService`1.GetObject() in D:\work\platform\Werp.Controller.Services\GridReadService.cs:94
Werp.View.Ext.Handlers.ReadHandler.ProcessRequest(HttpContext context) in D:\work\platform\Werp.View.Ext\Handlers\ReadHandler.ashx.cs:166
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +100
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
simple example to reproduce bug:
entity:
[Serializable]
[HierarchyRoot]
public class MyEntity : Entity
{
[Field, Key]
public int Id { get; private set; }
[Field]
public int Number { get; set; }
}
and code:
using (Session.Open(domain))
{
using (var transactionScope = Transaction.Open())
{
var helloWorld = new MyEntity { Number = int.MaxValue };
var helloWorld2 = new MyEntity { Number = int.MaxValue };
transactionScope.Complete();
}
using (var transactionScope = Transaction.Open())
{
FutureScalar<int> futureAggregate;
MyEntity[] query;
try
{
futureAggregate = Query.ExecuteFutureScalar(() => Query.All<MyEntity>().Sum(a => a.Number));
query = Query.All<MyEntity>().ToArray();
}
catch (StorageException e)
{
futureAggregate = Query.ExecuteFutureScalar(() => Query.All<MyEntity>().Count());
query = Query.All<MyEntity>().ToArray();
}
foreach (var myEntity in query)
Console.WriteLine(myEntity.Number);
transactionScope.Complete();
}
}
checked on sql 2008 and DO 4.3.5
asked
Sep 13 '10 at 05:06
pil0t
207●57●57●63
There is definitely an issue with query itself, but I see one more issue with this example: in your
catch
clause current transaction must already be blocked anyway (because of error). So you need a new nested transaction here.