【发布时间】:2015-01-14 19:58:19
【问题描述】:
通常它工作正常,但在某些情况下(我无法重现它)我收到带有堆栈跟踪的 NullReferenceException:
在 C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 1505 中的 Npgsql.NpgsqlCommand.ClearPoolAndCreateException(Exception e) 在 C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 650 中的 Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb) 在 C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 499 中的 Npgsql.NpgsqlCommand.ExecuteBlind() 在 C:\projects\Npgsql2\src\Npgsql\NpgsqlTransaction.cs:line 185 中的 Npgsql.NpgsqlTransaction.Rollback() 在 C:\projects\Npgsql2\src\Npgsql\NpgsqlTransaction.cs:line 141 中的 Npgsql.NpgsqlTransaction.Dispose(Boolean disposing) 在 NHibernate.Transaction.AdoTransaction.Dispose(Boolean isDisposing) 在 p:\nhibernate-core\src\NHibernate\Transaction\AdoTransaction.cs:line 368 在 NHibernate.Impl.SessionImpl.Close() 在 p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 380 在 NHibernate.Impl.SessionImpl.Dispose(Boolean isDisposing) 在 p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 1738 在 NHibernate.Impl.SessionImpl.Dispose() 在 p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 1709 public virtual IEnumerable<User.PublishedInfo> GetUsersByXP(int count)
{
using (ISession session = SessionFactory.OpenSession())
{
using (session.BeginTransaction())
{
var result = session.CreateCriteria<User>()
.SetProjection(PublishedUserProjections)
.AddOrder(Order.Desc("XP"))
.SetMaxResults(count)
.SetResultTransformer(Transformers.AliasToBean<User.PublishedInfo>())
.List<User.PublishedInfo>();
foreach (var r in result)
r.Initialize();
session.Transaction.Commit();
return result; // this line
}
}
}
这里可能有什么问题?
更新
有时在同一个代码片段中(但在 BeginTransaction 中)我收到异常“获取连接时超时”。也许这有某种关联。
【问题讨论】:
-
可能是因为有时会话中的事务根本没有初始化,然后内部带有
session.BeginTransaction()的using块试图处理实际上不存在的东西?简单地说,我会尝试在这个块中初始化一个事务变量,并且只有当它不为空时才提交它。此外,当发生事务以外的错误时会发生什么?我在任何地方都看不到任何回滚... -
@WillMarcouiller “当发生交易以外的错误时会发生什么?”我不在乎,因为只有读取操作。 “有时会话中的事务根本没有初始化” - 它应该在进入 using 块之前引发异常。 “仅当它不为空时才提交。” NullReference 不在我的代码中。它在调用 ISession.Dispose 时被抛出。
-
我明白了。但是,如果它只读取,为什么首先调用
BeginTransaction方法?如果我相信方法的名称,我会认为它只从底层数据库中读取,正如GetUsersByXP所说。这里不需要交易。另外,实践是分配一个变量,该变量应在 using 块中处理,然后 .NET 确切地知道要处理什么。在这里,正如我所看到的,我猜想在处理会话时存在某种混淆,因为已调用BeginTransaction方法并且事务中没有保留任何特定引用。 -
“为什么首先调用 BeginTransaction 方法?”因为有行规和同步。 “事务中没有特定的引用” 引用是由编译器隐式创建的,否则它不知道应该调用哪个对象 Dispose。它只是一个语法糖。
标签: c# postgresql nhibernate connection-pooling npgsql