我正在使用带有事务的 Spring Data JPA 开发应用程序。 尽管我使用的 Spring 版本 (4.0.0) 能够使用 JavaConfig,但我更喜欢坚持使用 XML。 我有这个配置: <beans xmlns="http://www.springframework.org/sc ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
通常它可以正常工作,但在某些情况下(我无法重现),我收到带有stacktrace的NullReferenceException:
at Npgsql.NpgsqlCommand.ClearPoolAndCreateException(Exception e) in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 1505 at Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb) in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 650 at Npgsql.NpgsqlCommand.ExecuteBlind() in C:\projects\Npgsql2\src\Npgsql\NpgsqlCommand.cs:line 499 at Npgsql.NpgsqlTransaction.Rollback() in C:\projects\Npgsql2\src\Npgsql\NpgsqlTransaction.cs:line 185 at Npgsql.NpgsqlTransaction.Dispose(Boolean disposing) in C:\projects\Npgsql2\src\Npgsql\NpgsqlTransaction.cs:line 141 at NHibernate.Transaction.AdoTransaction.Dispose(Boolean isDisposing) in p:\nhibernate-core\src\NHibernate\Transaction\AdoTransaction.cs:line 368 at NHibernate.Impl.SessionImpl.Close() in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 380 at NHibernate.Impl.SessionImpl.Dispose(Boolean isDisposing) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 1738 at NHibernate.Impl.SessionImpl.Dispose() in 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
}
}
}
这里可能有什么错误?
UPDATE
有时在同一代码段中(但在BeginTransaction中),我会收到一个异常“连接时超时”。 也许这与某种原因有关。
我在2.0.14.3中看到了同样的事情。 您正在运行哪个版本? 哪个版本的NHibernate?
查看代码,我发现
internal NpgsqlException ClearPoolAndCreateException(Exception e)
{
Connection.ClearPool();
return new NpgsqlException(resman.GetString("Exception_ConnectionBroken"), e);
}
2.2似乎同样遭受苦难
与大多数其他操作一样,对Connection属性始终执行null检查。 这可能是一个错误,但似乎在master分支中也进行了大量重写。
我能找到的唯一可以真正将连接内部设置为null的来源(除非由NHibernate以某种方式完成,但我对此表示怀疑)将是是否要处置NpgsqlCommand,然后从NpgsqlDataReader中读取。
编辑:
根据消息来源,如果NpgsqlTransaction仍然具有连接且事务处于活动状态,则将在Dispose上调用回滚。 在您的情况下,提交应该将其设置为null。 您正在使用using块中的session.Transaction(与存储从BeginTransaction()调用返回的引用相对)的事实可能是罪魁祸首,因为对session.Transaction的调用会隐式创建事务(如果会话中不存在任何事务) 。 这可能会导致commit调用实际上只是提交给空事务,然后在使用BeginTransaction创建的事务上调用Dispose。
在运行此代码时,您是否有任何多线程或异步代码可用于您的会话?
在我看来,如果事务内发生某些错误,它将引发异常并处置会话/事务。 尝试...
using (ISession session = SessionFactory.OpenSession())
{
List<User.PublishedInfo> results = null;
ITransaction transaction = null;
try
{
transaction = session.BeginTransaction();
results = session.CreateCriteria<User>()
.SetProjection(PublishedUserProjections)
.AddOrder(Order.Desc("XP"))
.SetMaxResults(count)
.SetResultTransformer(Transformers.AliasToBean<User.PublishedInfo>())
.List<User.PublishedInfo>();
foreach (var r in results)
r.Initialize();
transaction.Commit();
}
catch(Exceptionn ex)
{
if (transaction != null)
transaction.Rollback();
throw;
}
return results;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.