C# 在NHibernate 3.1中更新时崩溃
我正在编写项目并使用NHibernate 3.1 简单测试:C# 在NHibernate 3.1中更新时崩溃,c#,.net,hibernate,nhibernate,concurrency,C#,.net,Hibernate,Nhibernate,Concurrency,我正在编写项目并使用NHibernate 3.1 简单测试: IUserRepository userRepository = new UserRepository(SessionFactory); var admin = userRepository.GetByName("admin"); admin.Profile.Signature = "Signature"; userRepository.Update(admin); 实
IUserRepository userRepository = new UserRepository(SessionFactory);
var admin = userRepository.GetByName("admin");
admin.Profile.Signature = "Signature";
userRepository.Update(admin);
实现存储库。更新():
您不能混淆分支else中的call session.SaveOrUpdate(实体),因为如果在外部事务中调用了更新,则这是必需的
- 首先,我接收到版本为1的admin。他的状态是持续的
- 我改变任何财产的价值
- 我会更新
- 当流到达行
tx.Commit()时代码>,NHibernate生成一个查询: 更新用户 设置版本=2, 名称='admin', EncryptedPassword='21232f297a57a5a743894a0e4a801fc3', 电子邮件admin@admin.com', i激活=1, IsBanked=0, CommentsNumber=0, 角色='Admin', FirstName='Alexey', LastName='Kovpaev', 出生日期='1992-01-02T12:00:00.00', About='Just admin', 签名='Signature' 其中UserId='e23056df-d934-4880-b6b8-f2128cd41504' 和版本=1
- NHibernate引发异常:NHibernate.StaleObjectStateException:行被另一个事务更新或删除(或未保存的值映射不正确)
using (var tx = Session.BeginTransaction())
{
var admin = Session.CreateCriteria<User>().Add(Restrictions.Eq("Name", "admin")).UniqueResult<User>();
admin.Profile.Signature = "Signature";
Session.SaveOrUpdate(admin);
tx.Commit();
}
使用(var tx=Session.BeginTransaction())
{
var admin=Session.CreateCriteria().Add(Restrictions.Eq(“Name”,“admin”)).UniqueResult();
admin.Profile.Signature=“签名”;
Session.SaveOrUpdate(管理员);
tx.Commit();
}
首先,版本号是正确的。
其次,其他交易根本不存在。
为什么?我发现两个来源声称NHibernate不支持嵌套事务。建议的解决方案似乎是Ayendes UnitOfWork实现或将事务嵌套在TransactionScope中
在此代码中,没有嵌套事务。不能进行多个级别的嵌套,因为它是在“if”块中检查的。我没有正确阅读您的代码。您明确地确保没有嵌套。好啊我想知道你的用户存储库。它如何管理会话?GetByName是在内部打开和关闭会话,还是在UserRepository的生命周期内保持一个会话打开?这段代码来自单元测试,有一个非常简单的会话管理。它创建一个会话,并在所有测试中使用它。在异常出现时,会话只有一个持久实体。它是管理员,具有正确的id和版本。您是否使用MSTest并运行其他单元测试?MSTest将并行运行您的测试,因此您需要执行锁定以确保两个测试不会同时使用会话。如果这是您唯一的测试,或者您没有使用并行运行测试的测试框架,我就没有主意了。这很好,至少有人愿意帮助)我使用NUnit,并且与其他测试分开运行此测试,所以这应该没有问题。我想我遗漏了一些明显的细节,有经验的人应该会很快看到,但因为我是第一次使用NHibernate,所以我找不到它。
using (var tx = Session.BeginTransaction())
{
var admin = Session.CreateCriteria<User>().Add(Restrictions.Eq("Name", "admin")).UniqueResult<User>();
admin.Profile.Signature = "Signature";
Session.SaveOrUpdate(admin);
tx.Commit();
}