문제

나를 완전히 혼란스럽게 만드는 것 중 하나는 session.Flush,와 함께 session.Commit, 그리고 session.Close.

때때로 session.Close 예를 들어 필요한 모든 변경 사항을 커밋합니다.오류가 발생할 경우 롤백을 선택할 수 있도록 트랜잭션이 있거나 여러 생성/업데이트/삭제 작업 단위가 있을 때 커밋을 사용해야 한다는 것을 알고 있습니다.

하지만 가끔은 그 뒤에 숨은 논리 때문에 정말 당황스러울 때도 있어요. session.Flush.나는 당신이 session.SaveOrUpdate() 플러시가 이어지지만 플러시를 제거하면 어쨌든 잘 작동합니다.가끔 Flush 문에서 세션 시간이 초과되었다는 오류가 발생했는데 이를 제거하면 해당 오류가 발생하지 않았는지 확인했습니다.

Flush를 언제 어디서 사용해야 하는지에 대한 좋은 지침이 있는 사람이 있나요?이에 대한 NHibernate 문서를 확인했지만 여전히 간단한 대답을 찾을 수 없습니다.

도움이 되었습니까?

해결책

간단히:

  1. 항상 트랜잭션 사용
  2. 사용하지 마세요 Close(), 대신에 통화를 마무리하세요. ISession 안에 using 진술 또는 ISession의 수명주기를 다른 곳에서 관리하세요..

에서 문서:

때때로 ISession ADO.NET 연결 상태를 메모리에 있는 개체 상태와 동기화하는 데 필요한 SQL 문을 실행합니다.이 플러시 프로세스는 기본적으로 다음 지점에서 발생합니다.

  • 일부 호출에서 Find() 또는 Enumerable()
  • ~에서 NHibernate.ITransaction.Commit()
  • ~에서 ISession.Flush()

SQL문은 다음 순서로 발행됩니다.

  1. 모든 엔터티 삽입은 해당 개체가 다음을 사용하여 저장되는 순서와 동일합니다. ISession.Save()
  2. 모든 엔터티 업데이트
  3. 모든 컬렉션 삭제
  4. 모든 수집 요소 삭제, 업데이트 및 삽입
  5. 모든 컬렉션 삽입
  6. 모든 엔터티 삭제, 해당 개체가 다음을 사용하여 삭제된 것과 동일한 순서로 ISession.Delete()

(단, 기본 ID 생성을 사용하는 개체는 저장 시 삽입됩니다.)

명시적으로 말한 경우를 제외하고 Flush(), 세션이 ADO.NET 호출을 실행하는 시기에 대해서는 전혀 보장할 수 없으며 실행 순서만 보장됩니다..그러나 NHibernate는 다음을 보장합니다. ISession.Find(..) 메서드는 오래된 데이터를 반환하지 않습니다.또한 잘못된 데이터를 반환하지도 않습니다.

플러시가 덜 자주 발생하도록 기본 동작을 변경할 수 있습니다.그만큼 FlushMode 클래스는 세 가지 모드를 정의합니다.커밋 시에만 플러시됩니다(그리고 NHibernate가 ITransaction API가 사용됨), 설명된 루틴을 사용하여 자동으로 플러시하거나, 그렇지 않은 경우 플러시하지 마십시오. Flush() 명시적으로 호출됩니다.마지막 모드는 장기 실행 작업 단위에 유용합니다. ISession 오랫동안 열려 있고 연결이 끊어진 상태로 유지됩니다.

...

또한 참조하십시오 이 구역:

세션 종료에는 다음과 같은 네 가지 단계가 포함됩니다.

  • 세션을 플러시하다
  • 트랜잭션을 커밋하다
  • 세션을 닫아
  • 예외 처리

세션 플러시

혹시 다음을 사용하게 된다면 ITransaction API에서는 이 단계에 대해 걱정할 필요가 없습니다.트랜잭션이 커밋될 때 암시적으로 수행됩니다.그렇지 않으면 전화해야 합니다. ISession.Flush() 모든 변경 사항이 데이터베이스와 동기화되도록 합니다.

데이터베이스 트랜잭션 커밋

NHibernate ITransaction API를 사용하는 경우 다음과 같습니다.

tx.Commit(); // flush the session and commit the transaction

ADO.NET 트랜잭션을 직접 관리하는 경우 수동으로 수행해야 합니다. Commit() ADO.NET 트랜잭션.

sess.Flush();
currentTransaction.Commit();

변경 사항을 커밋하지 않기로 결정한 경우:

tx.Rollback();  // rollback the transaction

또는:

currentTransaction.Rollback();

트랜잭션을 롤백하는 경우 Hibernate의 내부 상태가 일관되도록 보장하기 위해 즉시 현재 세션을 닫고 폐기해야 합니다.

ISession 닫기

전화 ISession.Close() 세션의 끝을 표시합니다.Close()의 주요 의미는 세션에 의해 ADO.NET 연결이 해제된다는 것입니다.

tx.Commit();
sess.Close();

sess.Flush();
currentTransaction.Commit();
sess.Close();

자신만의 연결을 제공한 경우 Close() 이에 대한 참조를 반환하므로 수동으로 닫거나 풀로 반환할 수 있습니다.그렇지 않으면 Close() 수영장으로 돌려보내줍니다.

다른 팁

NHibernate 2.0부터 DB 운영을 위해서는 트랜잭션이 필요합니다.그러므로, ITransaction.Commit() 호출은 필요한 모든 플러시를 처리합니다.어떤 이유로 NHibernate 트랜잭션을 사용하지 않는 경우 세션이 자동으로 플러시되지 않습니다.

때때로 ISession은 ADO.NET 연결 상태를 메모리에 있는 개체의 상태와 동기화하는 데 필요한 SQL 문을 실행합니다.

그리고 항상 사용

 using (var transaction = session.BeginTransaction())
 {
     transaction.Commit();
 }

이 변경 사항보다 변경 사항이 커밋된 후 데이터베이스에 저장하려면 transaction.Commit()을 사용합니다.

다음은 session.Flush()가 없으면 실패하는 코드의 두 가지 예입니다.

http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html

마지막에는 ID 삽입을 설정하고 엔터티를 저장한 다음 플러시한 다음 ID 삽입을 끄는 코드 섹션을 볼 수 있습니다.이 플러시가 없으면 ID 삽입을 설정하고 해제한 다음 엔터티를 저장하는 것처럼 보였습니다.

Flush()를 사용하면 무슨 일이 일어나고 있는지 더 잘 제어할 수 있게 되었습니다.

또 다른 예는 다음과 같습니다.

TransactionScope 내에서 NServiceBus 메시지 보내기

나는 이것에 대한 이유를 완전히 이해하지 못하지만 Flush()는 내 오류가 발생하는 것을 방지했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top