2017-10-10 9 views
1

내 컨트롤러 :중복 항목 'XXX'

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 (?, ?, ?)]

오류가 결코 그냥 이야기 나와, 자산 (제 1 개체 저장)에 변화가 없습니다 색상 요소.

오류 메시지는 데이터베이스에 id = XXX (또는 ID가 YYY 인 색상)이 있고 다른 사용자가 나를 초 추가 한 것이므로 정확합니다.

배경 정보 :

  • 는 동시성 문제입니다 날 것으로 보인다. 나는 Isession이 스레드 안전하지 않다는 것을 알고 있지만, 절름발이 MySQL 또는 NHibernate는 그것을 처리하는 방법을 모른다. 그래서, 나는 틀린 일을하고 있다고 확신합니다.

  • 나는 오류가 간헐적으로 발생한다고 생각한다. MySQL이나 NHibernate가 똑같은 id를 가진 다른 이야기 나 색을 항상 가지고 있기 때문이다.

  • SQL Server에서 마이그레이션하면 코드가 제대로 작동합니다. 지난 3 일 동안 성공하지 못했습니다.

  • ID를 설정하지 않았습니다. 그것이 이해가되는지 모르겠다 ...하지만 NHibernate가 Color/Story에게 ID를 제공한다고 생각하지만, 트랜잭션을 커밋 할 때 ID는 더 이상 사용할 수 없다. 도움이 될

한가지 더 ... 내 마지막 테스트 동안

는 자 NHibernate는 .NET 예외를 발사 한 후 ID (이미) = 320,962와 함께 스토리를 저장하려고.

그런 다음 저장 버튼을 다시 클릭하고 NHibernate가 ID = 320963 (320962 + 1)의 스토리를 저장하려고했습니다.

그런 다음, 저장 버튼을 세 번 클릭하고 NHibernate가 ID = 320964 (320962 + 2)로 스토리를 저장하려고 시도했습니다.

이 3 개의 ID를 모두 사용할 수 없으므로 그 중 아무 것도 작동하지 않았습니다. NHibernate는 이러한 ID를 "기억"한다고 생각 했습니까?

답변

0

난 그냥 내 매핑을 변경하는 데 필요한 :

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

MySQL은 SQL 서버가 수행하는 다른 방법으로 자동 증가 열을 처리하는 것 같다.

+0

답변을 수락하십시오! –