NHibernate Aurora (MySQL) 中键 'PRIMARY' 的重复条目 'XXX'
Duplicate entry 'XXX' for key 'PRIMARY' in NHibernate Aurora (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 (?)]
或
Duplicate entry 'YYY' for key 'PRIMARY' transaction could not insert:
[K1.Domain.Color#YYY][SQL: INSERT INTO Color
(name, asset_id,
id) VALUES (?, ?, ?)]
Asset(保存的第一个实体)永远不会发生错误,只是 Story 或 Color 实体。
错误消息是绝对正确的,因为它在数据库中确实存在一个 ID = XXX(或颜色 ID = YYY)的故事,由另一个用户在我之前几秒添加。
背景资料:
在我看来这是一个并发问题。
我知道 ISession 不是线程安全的,但它看起来很蹩脚 MySQL 或者 NHibernate 不知道如何处理它。所以,我很确定我做错了什么。
我认为错误会间歇性发生,因为并不总是会有另一个具有相同 ID MySQL/NHibernate 的 Story 或 Color 尝试使用。
我们从 SQL 服务器迁移,我们的代码运行良好。
我们花了最后 3 天时间深入研究这个问题,但没有成功。
我没有设置任何ID。
我不知道这是否有意义...但我认为 NHibernate 给了 Color/Story 一个 ID(目前可用),但是,当我提交事务时,该 ID 不再可用。
还有一件事可能会有所帮助...
在我上次测试期间,NHibernate 试图保存 ID = 320962 的 Story(它已经存在),然后 .NET 触发了异常。
然后我再次单击“保存”按钮,NHibernate 尝试保存 ID = 320963 (320962 + 1) 的 Story。
然后,我第三次单击“保存”按钮,NHibernate 尝试保存 ID = 320964 (320962 + 2) 的 Story。
None 然后工作,因为所有这 3 个 ID 都不可用。
NHibernate 是否应该 "remember" 这些 id?
我只需要将映射更改为:
Id(x => x.id).GeneratedBy.Identity();
似乎 MySQL 以不同的方式处理自动递增列 SQL 服务器。
我的控制器:
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 (?)]
或
Duplicate entry 'YYY' for key 'PRIMARY' transaction could not insert: [K1.Domain.Color#YYY][SQL: INSERT INTO
Color
(name, asset_id, id) VALUES (?, ?, ?)]
Asset(保存的第一个实体)永远不会发生错误,只是 Story 或 Color 实体。
错误消息是绝对正确的,因为它在数据库中确实存在一个 ID = XXX(或颜色 ID = YYY)的故事,由另一个用户在我之前几秒添加。
背景资料:
在我看来这是一个并发问题。 我知道 ISession 不是线程安全的,但它看起来很蹩脚 MySQL 或者 NHibernate 不知道如何处理它。所以,我很确定我做错了什么。
我认为错误会间歇性发生,因为并不总是会有另一个具有相同 ID MySQL/NHibernate 的 Story 或 Color 尝试使用。
我们从 SQL 服务器迁移,我们的代码运行良好。 我们花了最后 3 天时间深入研究这个问题,但没有成功。
我没有设置任何ID。 我不知道这是否有意义...但我认为 NHibernate 给了 Color/Story 一个 ID(目前可用),但是,当我提交事务时,该 ID 不再可用。
还有一件事可能会有所帮助...
在我上次测试期间,NHibernate 试图保存 ID = 320962 的 Story(它已经存在),然后 .NET 触发了异常。
然后我再次单击“保存”按钮,NHibernate 尝试保存 ID = 320963 (320962 + 1) 的 Story。
然后,我第三次单击“保存”按钮,NHibernate 尝试保存 ID = 320964 (320962 + 2) 的 Story。
None 然后工作,因为所有这 3 个 ID 都不可用。 NHibernate 是否应该 "remember" 这些 id?
我只需要将映射更改为:
Id(x => x.id).GeneratedBy.Identity();
似乎 MySQL 以不同的方式处理自动递增列 SQL 服务器。