[java] Hibernate에서 session.flush ()의 용도는 무엇입니까?

레코드를 업데이트 할 때 session.flush()Hibernate와 함께 사용할 수 있습니다 . 무엇이 필요 flush()합니까?



답변

세션을 플러시하면 Hibernate가의 메모리 내 상태를 Session데이터베이스와 동기화 합니다 (즉, 변경 사항을 데이터베이스에 기록). 기본적으로 Hibernate는 자동으로 변경 사항을 플러시합니다.

  • 일부 쿼리 실행 전
  • 트랜잭션이 커밋 될 때

명시 적으로 플러시를 허용하면 Session일부 상황 (ID 할당, 세션 크기 제어 등)에서 필요할 수있는 더 세밀한 제어가 제공됩니다.


답변

위의 답변에서 올바르게 말했듯이 호출 flush()하면 데이터베이스에서 SQL 명령을 실행하도록 최대 절전 모드를 강제 실행합니다. 그러나 변경 사항은 아직 “커밋”되지 않았 음을 이해하십시오. 따라서 플러시를 수행 한 후 커밋을 수행하기 전에 DB에 직접 액세스하고 (예 : SQL 프롬프트에서) 수정 된 행을 확인하면 변경 사항이 표시되지 않습니다.

이것은 2 개의 SQL 명령 세션을 여는 것과 같습니다. 그리고 한 세션에서 수행 된 변경 사항은 커밋 될 때까지 다른 사용자에게 표시되지 않습니다.


답변

나는 우리가 호출 할 때 우리 session.flush()의 명령문이 데이터베이스에서 실행되지만 커밋되지 않는다는 것을 알고 있습니다.

flush()세션 객체에서 메서드를 호출하지 않고 commit 메서드를 호출하면 내부적으로 데이터베이스에서 명령문을 실행 한 다음 커밋하는 작업을 수행 한다고 가정 합니다.

commit=flush+commit (기능의 경우)

따라서 Session 객체에 대해 flush () 메서드를 호출하면 커밋되지 않고 데이터베이스에 도달하고 쿼리를 실행하고 롤백도 수행된다는 결론을 내립니다.

커밋하기 위해 Transaction 객체에 commit ()을 사용합니다.


답변

세션을 플러시하면 현재 세션에있는 데이터가 데이터베이스에있는 것과 동기화됩니다.

Hibernate 웹 사이트에 대한 추가 정보 :

flush()세션이 JDBC 호출을 실행하는시기에 대한 보장이 전혀없고 실행되는 순서 만 보장 할 수 없기 때문에 유용합니다 flush().


답변

flush트랜잭션이 커밋 될 때가 아니라 알려진 위치에서 유효성 검사 제약 조건이 실현되고 감지되도록 강제 하는 데 사용할 수 있습니다 . commit선언적 논리, 컨테이너 또는 템플릿을 통해 일부 프레임 워크 논리에 의해 암시 적으로 호출 될 수 있습니다 . 이 경우 throw되는 예외는 포착 및 처리하기 어려울 수 있습니다 (코드에서 너무 높을 수 있음).

예를 들어 save()주소에 고유 한 제약 조건이있는 새 EmailAddress 객체 인 경우 커밋 할 때까지 오류가 발생하지 않습니다.

호출 flush()하면 행이 강제로 삽입되고 중복이있는 경우 예외가 발생합니다.

그러나 예외 후에 세션을 롤백해야합니다.


답변

위의 모든 답변을 클럽 화하고 Flush () 메서드를 Session.save ()와 연결하여 더 중요하게 만들고 싶습니다.

Hibernate save ()는 엔티티를 데이터베이스에 저장하는 데 사용할 수 있습니다. 트랜잭션 외부에서이 메서드를 호출 할 수 있으므로이 메서드가 데이터를 저장하는 것을 좋아하지 않습니다. 트랜잭션없이 이것을 사용하고 엔터티간에 캐스 케이 딩이있는 경우 세션을 플러시하지 않는 한 기본 엔터티 만 저장됩니다.

flush () : 세션을 강제로 플러시합니다. 세션 데이터를 데이터베이스와 동기화하는 데 사용됩니다.

session.flush ()를 호출하면 명령문이 데이터베이스에서 실행되지만 커밋되지는 않습니다. session.flush ()를 호출하지 않고 session.commit ()을 호출하면 내부적으로 commit () 메서드가 문을 실행하고 커밋합니다.

그래서 commit () = flush + commit. 따라서 session.flush ()는 데이터베이스에서 명령문을 실행하고 (커밋은 아님) 명령문은 더 이상 메모리에 없습니다. 세션을 강제로 플러시합니다.

몇 가지 중요한 사항 :

트랜잭션 경계 외부에 저장하는 것을 피해야합니다. 그렇지 않으면 매핑 된 엔티티가 저장되지 않아 데이터 불일치가 발생합니다. 예외 나 경고가 발생하지 않기 때문에 세션 플러시를 잊어 버리는 것은 매우 정상입니다. 기본적으로 Hibernate는 자동으로 변경 사항을 플러시합니다 : 트랜잭션이 커밋 될 때 일부 쿼리 실행 전에 Session을 명시 적으로 플러시하도록 허용하면 일부 상황에서 필요할 수있는 더 미세한 제어를 제공합니다 (ID 할당, 세션 크기 제어). )


답변

flush() 메서드는 Hibernate가 세션을 플러시하도록합니다. setFlushMode()메서드 를 사용하여 세션에 대해 플러시 모드를 사용하도록 Hibernate를 구성 할 수 있습니다 . 현재 세션의 플러시 모드를 얻으려면 getFlushMode()메서드 를 사용할 수 있습니다 . 세션이 더티 여부를 확인하려면 isDirty()방법 을 사용할 수 있습니다 . 기본적으로 Hibernate는 세션 비우기를 관리합니다.

문서에 명시된대로 :

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

홍조

플러싱은 지속성 컨텍스트의 상태를 기본 데이터베이스와 동기화하는 프로세스입니다. EntityManager및 하이버 네이트 Session애플리케이션 개발자 엔티티의 지속 상태를 변경할 수있는 방법들의 세트를 노출시킨다.

지속성 컨텍스트는 모든 엔터티 상태 변경을 큐에 넣는 트랜잭션 쓰기 숨김 캐시 역할을합니다. 모든 write-behind 캐시와 마찬가지로 변경 사항은 먼저 메모리에 적용되고 플러시 시간 동안 데이터베이스와 동기화됩니다. 플러시 작업은 모든 엔티티 상태 변경을 가져 와서 INSERT, UPDATE또는 DELETE문으로 변환합니다 .

플러싱 전략은 현재 실행중인 Hibernate 세션 의 flushMode 에 의해 제공됩니다 . JPA는 두 가지 플러시 전략 ( AUTOCOMMIT) 만 정의하지만 Hibernate는 훨씬 더 광범위한 플러시 유형 스펙트럼을 가지고 있습니다.

  • ALWAYS: 모든 쿼리 전에 세션을 플러시합니다.
  • AUTO: 이것은 기본 모드이며 필요한 경우에만 세션을 플러시합니다.
  • COMMIT: 세션은 너무 일찍 플러시 될 수 있지만 현재 트랜잭션이 커밋 될 때까지 플러시를 지연하려고합니다.
  • MANUAL: 세션 플러싱은 Session.flush()지속성 컨텍스트 변경 사항을 적용하기 위해 명시 적으로 호출해야하는 응용 프로그램에 위임 됩니다.

기본적으로 Hibernate는 AUTO다음 상황에서 플러시를 트리거하는 플러시 모드를 사용합니다 .

  • 거래를 수행하기 전에
  • 대기중인 엔티티 작업과 겹치는 JPQL / HQL 쿼리를 실행하기 전에
  • 등록 된 동기화가없는 네이티브 SQL 쿼리를 실행하기 전에