2017-10-10 143 views
1

我的控制器:重复项 '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不再可用。

一两件事,可以帮助...

在我的最后一次测试,NH​​ibernate的试图挽救故事与ID = 320962(已经存在),然后.NET发射除外。

然后我再次单击保存按钮,NHibernate试图保存ID = 320963(320962 + 1)的故事。

然后,我点击第三次保存按钮,NHibernate尝试保存ID = 320964(320962 + 2)的故事。

之后没有工作,因为所有这3个ID都不可用。 NHibernate是否设想“记住”这些ID?

回答

0

我只是需要改变我的映射:

Id(x => x.id).GeneratedBy.Identity(); 

看来MySQL的处理方式不同SQL Server会自动增量列。

+0

接受你的答案! –