IT

Java - JPA - @Version 주석

itgroup 2022. 12. 7. 22:24
반응형

Java - JPA - @Version 주석

어떻게요?@Version주석 작업을 JPA로 수행합니까?

나는 다음과 같은 발췌의 다양한 답변을 발견했다.

JPA는 엔티티의 버전 필드를 사용하여 동일한 데이터스토어 레코드에 대한 동시 수정을 감지합니다.JPA 런타임은 동일한 레코드를 동시에 수정하려는 시도를 검출하면 마지막으로 커밋을 시도하는 트랜잭션에 예외를 발생시킵니다.

하지만 나는 여전히 그것이 어떻게 작동하는지 확신하지 못한다.


또한 다음 행에서와 같습니다.

버전 필드는 변경할 수 없습니다.필드 값을 변경하면 결과가 정의되지 않았습니다.

즉, 버전필드로 선언해야 한다는 의미입니까?final?

하지만 나는 여전히 그것이 어떻게 작동하는지 확신하지 못한다.

엔티티라고 합시다.MyEntity주석이 붙어 있다.version속성:

@Entity
public class MyEntity implements Serializable {    

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @Version
    private Long version;

    //...
}

업데이트 시 필드 주석:@Version증가하여 에 추가됩니다.WHERE절은 다음과 같습니다.

UPDATE MYENTITY SET ..., VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))

이 경우,WHERE(같은 엔티티가 다른 스레드에 의해 이미 갱신되었기 때문에) 구가 레코드에 일치하지 않으면 지속성 공급자는 다음 명령을 슬로우합니다.OptimisticLockException.

버전 필드를 최종 버전이라고 선언해야 한다는 의미입니까?

아니요, 하지만 세터를 보호하라고 부르면 안 되니까요.

@Pascal 답변은 완벽하게 유효하지만, 제 경험상 아래 코드는 최적의 잠금을 달성하는 데 도움이 됩니다.

@Entity
public class MyEntity implements Serializable {    
    // ...

    @Version
    @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
    private long version = 0L;

    // ...
}

왜요? 이유:

  1. 필드에 주석을 달면 낙관적인 잠금이 작동하지 않습니다.@Version실수로 설정되다null.
  2. 이 특수 필드는 반드시 오브젝트의 비즈니스 버전이 아니기 때문에 오해를 피하기 위해 다음과 같은 필드에 이름을 붙이는 것이 좋습니다.optlock보다는version.

첫 번째 포인트는 JPA 벤더가 강제하기 때문에 애플리케이션이 데이터베이스에 데이터를 삽입하기 위해 JPA만을 사용하는지는 중요하지 않습니다.0위해서@version필드 생성 시.그러나 대부분의 경우 플레인 SQL 문도 사용됩니다(적어도 유닛 및 통합 테스트 중).

엔티티가 데이터베이스에서 갱신될 때마다 버전 필드가 1씩 증가합니다.데이터베이스의 엔티티를 업데이트하는 모든 작업이 추가됩니다.WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE문의에 응답합니다.

jpa 프레임워크는 해당 운영 행을 확인할 때 로드와 지속 사이에 버전 번호가 증가하면 쿼리가 데이터베이스에서 엔티티를 찾을 수 없기 때문에 엔티티를 로드와 지속 사이에 동시에 수정하지 않음을 확인할 수 있습니다.

한 번에 하나의 업데이트만 수행하는 데 사용되는 버전입니다.JPA 공급자가 버전을 확인합니다. 예상 버전이 이미 증가하면 다른 사용자가 이미 엔티티를 업데이트하여 예외가 발생합니다.

따라서 엔티티 가치를 업데이트하는 것이 더 안전하고 낙관적입니다.

값이 자주 변경될 경우 버전 필드를 사용하지 않는 것이 좋습니다.예를 들어 "웹 페이지가 액세스할 때마다 증가하는 카운터 필드가 있는 도면요소"입니다.

정보를 조금 더 추가해 보겠습니다.

하지만, JPA를 통해 하지 않습니다.JPAUpdateClause이러한 경우 쿼리에 버전 증분을 수동으로 추가해야 합니다.

JPQL을 통한 업데이트도 마찬가지입니다.즉, 엔티티에 대한 단순한 변경이 아니라, 휴지 상태에 의해 갱신된 경우에도 데이터베이스에 대한 갱신 명령입니다.

페드로

언급URL : https://stackoverflow.com/questions/2572566/java-jpa-version-annotation

반응형