developer tip

Java-JPA-@Version 주석

optionbox 2020. 8. 5. 08:08
반응형

Java-JPA-@Version 주석


@VersionJPA에서 주석은 어떻게 작동합니까?

추출이 다음과 같은 다양한 답변을 찾았습니다.

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

그러나 나는 그것이 어떻게 작동하는지 여전히 확실하지 않습니다.


또한 다음 줄에서와 같이 :

버전 필드는 변경 불가능한 것으로 간주해야합니다. 필드 값을 변경하면 결과가 정의되지 않습니다.

버전 필드를 다음과 같이 선언해야한다는 의미 final입니까?


그러나 여전히 어떻게 작동하는지 잘 모르겠습니다.

엔터티 MyEntity에 주석이 달린 version속성 있다고 가정 해 봅시다 .

@Entity
public class MyEntity implements Serializable {    

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @Version
    private Long version;

    //...
}

업데이트시 주석이 달린 필드 @VersionWHERE다음과 같이 증분되고 절에 추가됩니다 .

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. 주석이 달린 필드 가 실수로로 설정된 경우 낙관적 잠금 이 작동하지 않습니다 .@Versionnull
  2. 이 특수 필드는 비즈니스의 객체 버전 일 필요는 없으므로 오도를 피하기 위해 이러한 필드의 이름을 sth optlock대신 sth로 지정하는 것을 선호합니다 version.

첫번째 점은 만약 애플리케이션 용도 상관 없다 JPA 벤더가 적용되는 바와 같이, 데이터베이스에 데이터를 삽입 JPA를 0위해 @version작성시에 필드. 그러나 거의 항상 일반 SQL 문도 사용 중입니다 (적어도 단위 / 통합 테스트 중).


데이터베이스에서 엔티티가 업데이트 될 때마다 버전 필드가 1 씩 증가합니다. 데이터베이스에서 엔티티를 업데이트하는 모든 작업은 WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE해당 쿼리에 추가 됩니다.

영향을받는 작업 행을 검사 할 때 jpa 프레임 워크는로드와 지속 사이에 버전 번호가 증가 된 경우 쿼리가 데이터베이스에서 엔티티를 찾지 못하므로 엔티티로드 및 지속 사이에 동시 수정이 없는지 확인할 수 있습니다.


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

따라서 엔터티 값을 업데이트하는 것이 더 안전하고 낙관적입니다.

값이 자주 변경되면 버전 필드를 사용하지 않는 것을 고려할 수 있습니다. 예를 들어 "카운터 필드가있는 엔티티는 웹 페이지에 액세스 할 때마다 증가합니다"


조금만 더 정보를 추가하면됩니다.

JPA는 사용자를 대신하여 버전을 관리하지만을 통해 레코드를 업데이트 할 때는 업데이트하지 않습니다 JPAUpdateClause. 이러한 경우 쿼리에 버전 증분을 수동으로 추가해야합니다.

페드로

참고 URL : https://stackoverflow.com/questions/2572566/java-jpa-version-annotation

반응형