我的控制器:重复项 'XXX' 为NHibernate的极光键 '主要'(MySQL的)
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列是自动递增。
似乎一切都很好,但每过一段时间我得到这个错误:
Duplicate entry 'XXX' for key 'PRIMARY' transaction could not insert: [K1.Domain.Story#XXX][SQL: INSERT INTO
Story
(id) VALUES (?)]
OR
Duplicate entry 'YYY' for key 'PRIMARY' transaction could not insert: [K1.Domain.Color#YYY][SQL: INSERT INTO
Color
(name, asset_id, id) VALUES (?, ?, ?)]
错误从不与资产(第一实体保存)发生,只是故事或颜色实体。
错误消息是绝对正确的,因为它确实存在于数据库中的ID = XXX的故事(或ID为YYY的颜色),由另一个用户在我之前添加。
背景信息:
在我看来,这是一个并发的问题。 我知道ISession不是线程安全的,但它看起来很蹩脚MySQL或NHibernate不知道如何处理它。所以,我很确定我做错了什么。
我认为这个错误是间歇性发生的,只是因为并不总是会有另一个Story或Color与MySQL/NHibernate尝试使用的相同ID。
我们从SQL Server迁移,我们的代码工作得很好。 我们花了最后3天的时间挖掘这一切,但都没有成功。
我没有设置任何ID。 我不知道它是否合理......但我认为NHibernate为Color/Story提供了一个ID(此时可用),但是当我提交事务时,ID不再可用。
一两件事,可以帮助...
在我的最后一次测试,NHibernate的试图挽救故事与ID = 320962(已经存在),然后.NET发射除外。
然后我再次单击保存按钮,NHibernate试图保存ID = 320963(320962 + 1)的故事。
然后,我点击第三次保存按钮,NHibernate尝试保存ID = 320964(320962 + 2)的故事。
之后没有工作,因为所有这3个ID都不可用。 NHibernate是否设想“记住”这些ID?
接受你的答案! –