我的控制器:
using (ISession session = NHibernateSessionPerRequest.GetCurrentSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
// Changed for the sake of simplicity.
// What I meant was entities being saved without using Flush()
var asset = new Asset() { name = "test" };
session.Save(asset);
var story = new Story();
session.Save(story);
asset.stories.Add(story);
session.Save(asset);
var color = new Color() { name = colorName };
color.asset = asset;
session.Save(color);
transaction.Commit();
return Json(new { Status = "OK" });
}
catch (Exception ex)
{
if (!transaction.WasCommitted)
{
transaction.Rollback();
}
return Json(new { Status = "NOK", Mensagem = ex.Message, });
}
}
}
我的映射:
public AssetMap()
{
Id(x => x.id).GeneratedBy.Increment();
Map(x => x.name);
HasMany(x => x.stories);
}
public StoryMap()
{
Id(x => x.id).GeneratedBy.Increment();
}
public ColorMap()
{
Id(x => x.id).GeneratedBy.Increment();
Map(x => x.name);
References(x => x.asset);
}
所有id列都是自动增量。
一切似乎都很好,但是每当我收到这个错误的时候都是这样:
重复输入' XXX'关键' PRIMARY'交易无法插入: [K1.Domain.Story #XXX] [SQL:INSERT INTO
Story
(id)VALUES(?)]
OR
重复录入' YYY'关键' PRIMARY'交易无法插入: [K1.Domain.Color #YYY] [SQL:INSERT INTO
Color
(name,asset_id, id)VALUES(?,?,?)]
资产(第一个实体保存)不会发生错误,只有Story或Color实体。
错误信息是绝对正确的,因为它在数据库中确实存在id = XXX的故事(或ID = YYY的颜色),由我在我之前的另一位用户添加。
背景资料:
在我看来,这是一个并发问题。 我知道ISession不是线程安全的,但它看起来很蹩脚MySQL或NHibernate不知道如何对待它。所以,我很确定我做错了什么。
我认为错误是间歇性发生的,因为并不总是会有另一个故事或颜色与MySQL / NHibernate尝试使用相同的ID。
我们从SQL Server迁移,我们的代码运行得非常好。 我们花了最近3天时间没有成功。
我没有设置任何ID。 我不知道它是否有意义...但我认为NHibernate为Color / Story提供了一个ID(目前可用),但是,当我提交交易时,ID不再可用
还有一件事可能有帮助...
在我上次测试期间,NHibernate尝试使用ID = 320962(已经存在)保存Story,然后.NET解除了异常。
然后我再次单击“保存”按钮,NHibernate尝试使用ID = 320963(320962 + 1)保存Story。
然后,我第三次点击“保存”按钮,NHibernate尝试使用ID = 320964(320962 + 2)保存故事。
然后没有一个工作,因为所有这3个ID都不可用。 NHibernate是否想过要记得"这些ids?
答案 0 :(得分:0)
我只需要将我的映射更改为:
Id(x => x.id).GeneratedBy.Identity();
似乎MySQL以与SQL Server不同的方式处理自动增量列。