어제 동료들이 겪은 최대 절전 모드 문제에 대해. 최대 절전 모드의 가장 기본적인 것입니다. 나는 많은 사람들이 이 문제를 겪었고 매우 흔하다는 것을 이해합니다. 그러나 이 문제에 직면하면 종종 혼란스러워집니다.
인상을 깊게 하려면 그것이 무엇인지, 왜 그런지를 알아야 합니다.
그 후, 나는 단순히 원래의 Hibernate 프레임워크를 사용하여 몇 가지 검증을 수행하고 실행 SQL 인쇄 출력 콘솔을 열고 결론에 도달했습니다.
전제는 동일한 거래 도중에 다음과 같다는 것입니다.
1. sql 문인 session.createSQLQuery(sql).executeUpdate()를 사용하여 삽입하면 출력 스테이션이 sql 삽입 문을 인쇄한 다음 sql 문을 사용하여 session.createSQLQuery(sql).uniqueResult()를 수행합니다. ; 그리고 SQL 쿼리도 출력됩니다. 문제가 없으며 데이터를 쿼리할 수 있습니다.
2. 최대 절전 모드를 사용하여 작업을 캡슐화하고 session.save(entity);를 사용하여 삽입된 SQL 문을 출력하지 않습니다. 그런 다음 session.get(entity,id) 메서드를 사용합니다. 또한 SQL 쿼리 문을 인쇄하지 않지만 데이터를 쿼리할 수 있습니다. 트랜잭션 커밋문이 실행되면 삽입된 SQL문이 출력된다.
3. hibernate의 session.save(entity);를 사용하여 삽입한 다음 "HQL" 문을 사용하여 쿼리합니다. 효과는 위의 두 번째 지점과 동일합니다.
4. hibernate의 session.save(entity)를 사용하여 삽입하지만 출력 콘솔은 삽입된 SQL 문을 인쇄하지 않습니다. 그런 다음 sql 문을 사용하여 session.createSQLQuery(sql).uniqueResult()를 수행하면 SQL 쿼리 문이 인쇄됩니다. 문제가 발생하여 데이터를 쿼리할 수 없습니다. 이 경우 session.flush() 메서드를 사용하고, 쿼리하기 전에 플러시() 메서드를 실행하면 출력 콘솔에 삽입된 SQL 문이 인쇄됩니다. 다시 쿼리하면 데이터가 나옵니다.
확인이 완료된 후 위의 내용을 확인해 보았는데, 네 번째 사항은 개발 과정에서 자주 나타나는 현상으로 많은 분들이 접하셨을 텐데 계속해서 헷갈려 하시는 분들이 많습니다. 이것은 인상을 깊게 만들었습니다.
인쇄 콘솔 SQL에서 기본 최대 절전 모드 저장 방법의 작업 프로세스를 볼 수 있습니다.
1. 저장하려는 인스턴스가 이미 영속적 상태인지 확인하고, 그렇지 않은 경우 캐시에 저장합니다.
2. 저장할 인스턴스를 기반으로 insert SQL 문을 계획합니다. 계획만 있고 실행되지는 않습니다.
3. 이전에 계획된 insert 문은 트랜잭션이 커밋될 때 실행됩니다.
tx.commit()를 session.flush로 바꾸십시오. 이때 컨트롤은 insert 문을 출력하지만 새 레코드는 데이터베이스에 추가되지 않습니다.
플러시 방법의 주요 기능은 캐시를 정리하고 데이터베이스를 Hibernate 캐시와 강제로 동기화하여 데이터 일관성을 보장하는 것입니다. 주요 작업은 일련의 SQL 문을 데이터베이스에 보내고 이러한 SQL 문을 실행하는 것이지만 데이터베이스에 제출하지는 않습니다. 커밋 메서드는 먼저 플러시 메서드를 호출한 다음 트랜잭션을 커밋합니다. 이것이 바로 플러시를 호출할 때 레코드가 데이터베이스에 삽입되지 않는 이유입니다. 트랜잭션이 커밋될 때까지 데이터베이스 업데이트가 저장되지 않기 때문입니다. commit 메소드는 암시적으로 플러시를 호출하기 때문에 일반적으로 플러시 메소드를 명시적으로 호출하지 않습니다.
이것은 최대 절전 모드의 플러시 메커니즘입니다. 일부 복잡한 객체를 업데이트하고 저장하는 과정에서 데이터베이스 작업 순서의 변경 여부와 지연된 플러시가 프로그램 결과에 영향을 미치는지 여부를 고려해야 합니다. 실제로 영향이 있는 경우 Hibernate가 캐시에 기록된 작업을 데이터베이스로 플러시하도록 작업 순서를 유지해야 하는 위치에 플러시를 추가할 수 있습니다. 이는 보기에는 좋지 않을 수 있지만 매우 효과적입니다.
질문: session.save 메소드는 캐시에 저장되며 데이터베이스를 직접 쿼리하는 SQL에서는 찾을 수 없습니다.
플러시() 메소드 이후에 실행된 SQL이 인쇄되지만 여전히 데이터베이스에는 없습니다. 직접 SQL 쿼리로 데이터를 찾을 수 있습니다.
1. 플러시() 이후 엔터티 데이터는 어디에 저장됩니까? 캐시는 save() 메소드와 동일하므로 SQL이 캐시를 가져올 수 없습니다.
2. 플러시 방식 이후에는 데이터베이스에 데이터가 들어가지 않았기 때문에, session.createSQLQuery(sql)를 이용하여 직접 SQL을 쿼리하여 쿼리하는 곳이 어디인지 직접 확인해야 합니다.