我的控制器:重複項 '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?
接受你的答案! –