확장을 사용하여 DynamoDB 향상된 클라이언트 작업 사용자 지정 - AWS SDK for Java 2.x

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

확장을 사용하여 DynamoDB 향상된 클라이언트 작업 사용자 지정

DynamoDB 향상된 클라이언트 API는 매핑 작업 이외의 기능을 제공하는 플러그인 확장을 지원합니다. 확장은 두 가지 후크 메서드를 사용하여 읽기 및 쓰기 작업 중에 데이터를 수정합니다.

  • beforeWrite() - 쓰기 작업이 발생하기 전에 수정합니다.

  • afterRead() - 읽기 작업이 발생한 후 결과를 수정합니다.

일부 작업(예: 항목 업데이트)은 쓰기와 읽기를 모두 수행하므로 두 후크 메서드가 모두 호출됩니다.

확장 프로그램 로드 방법

확장은 확장 클라이언트 빌더에서 지정한 순서대로 로드됩니다. 하나의 확장이 이전 확장에 의해 변환된 값에 대해 작동할 수 있으므로 로드 순서가 중요할 수 있습니다.

기본적으로 향상된 클라이언트는 두 개의 확장을 로드합니다.

향상된 클라이언트 빌더로 기본 동작을 재정의하고 확장을 로드할 수 있습니다. 기본 확장자를 원하지 않는 경우에는 none을 지정할 수도 있습니다.

중요

자체 확장을 로드하는 경우 확장 클라이언트는 기본 확장을 로드하지 않습니다. 기본 확장 중 하나가 제공하는 동작을 원하는 경우 해당 확장을 확장 목록에 명시적으로 추가해야 합니다.

다음 예제에서는 verifyChecksumExtension 이름이 인 사용자 지정 확장을 로드하는 방법을 보여줍니다VersionedRecordExtension. 이 예제에서는 AtomicCounterExtension가 로드되지 않습니다.

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

사용 가능한 확장 세부 정보 및 구성

다음 섹션에서는 SDK에서 사용 가능한 각 확장에 대한 자세한 정보를 제공합니다.

를 사용하여 낙관적 잠금 구현 VersionedRecordExtension

VersionedRecordExtension 확장은 항목이 데이터베이스에 기록될 때 항목 버전 번호를 증가시키고 추적하여 낙관적 잠금을 제공합니다. 실제 지속 항목의 버전 번호가 애플리케이션이 마지막으로 읽은 값과 일치하지 않으면 쓰기가 실패하는 조건이 모든 쓰기에 추가됩니다.

구성

항목 버전 번호를 추적하는 데 사용할 속성을 지정하려면 테이블 스키마에서 숫자 속성에 태그를 지정하세요.

다음 코드 조각은 version 속성에 항목 버전 번호가 포함되도록 지정합니다.

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

동일한 정적 테이블 스키마 접근 방식이 다음 코드 조각에 나와 있습니다.

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

작동 방법

를 사용한 낙관적 잠금VersionedRecordExtension은 이러한 DynamoDbEnhancedClientDynamoDbTable 메서드에 다음과 같은 영향을 미칩니다.

putItem

새 항목에는 초기 버전 값 0이 할당됩니다. 로 구성할 수 있습니다@DynamoDbVersionAttribute(startAt = X).

updateItem

항목을 검색하고, 하나 이상의 속성을 업데이트하고, 변경 사항을 저장하려고 하면 클라이언트 측의 버전 번호와 서버 측의 버전 번호가 일치하는 경우에만 작업이 성공합니다.

성공하면 버전 번호가 자동으로 1씩 증가합니다. 로 구성할 수 있습니다@DynamoDbVersionAttribute(incrementBy = X).

deleteItem

DynamoDbVersionAttribute 주석은 효과가 없습니다. 항목을 삭제할 때 조건 표현식을 수동으로 추가해야 합니다.

다음 예제에서는 조건식을 추가하여 삭제된 항목이 읽은 항목인지 확인합니다. 다음 예제에서는 주석이 달린 빈의 속성recordVersion입니다@DynamoDbVersionAttribute.

// 1. Read the item and get its current version. Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build()); // `recordVersion` is the bean's attribute that is annotated with `@DynamoDbVersionAttribute`. AttributeValue currentVersion = item.getRecordVersion(); // 2. Create conditional delete with the `currentVersion` value. DeleteItemEnhancedRequest deleteItemRequest = DeleteItemEnhancedRequest.builder() .key(KEY) .conditionExpression(Expression.builder() .expression("recordVersion = :current_version_value") .putExpressionValue(":current_version_value", currentVersion) .build()).build(); customerTable.deleteItem(deleteItemRequest);
transactWriteItems
  • addPutItem:이 메서드의 동작은와 동일합니다putItem.

  • addUpdateItem:이 메서드의 동작은와 동일합니다updateItem.

  • addDeleteItem:이 메서드의 동작은와 동일합니다deleteItem.

batchWriteItem
  • addPutItem:이 메서드의 동작은와 동일합니다putItem.

  • addDeleteItem:이 메서드의 동작은와 동일합니다deleteItem.

참고

DynamoDB 글로벌 테이블은 동시 업데이트 간에 '마지막 라이터 성공' 조정을 사용합니다. 여기서 DynamoDB는 마지막 라이터를 결정하기 위해 최선을 다합니다. 글로벌 테이블을 사용하는 경우이 '마지막 라이터 성공' 정책은 모든 복제본이 결국 DynamoDB에서 결정한 마지막 쓰기를 기반으로 수렴되므로 잠금 전략이 예상대로 작동하지 않을 수 있음을 의미합니다.

비활성화 방법

낙관적 잠금을 비활성화하려면 @DynamoDbVersionAttribute 주석을 사용하지 마십시오.

를 사용하여 카운터 구현 AtomicCounterExtension

AtomicCounterExtension 확장은 레코드가 데이터베이스에 기록될 때마다 태그가 지정된 숫자 속성을 증가시킵니다. 시작 및 증분 값을 지정할 수 있습니다. 값을 지정하지 않으면 시작 값은 0으로 설정되고 속성 값은 1씩 증가합니다.

구성

어떤 속성이 카운터인지 지정하려면 테이블 스키마에서 Long 유형의 속성에 태그를 지정하세요.

다음 코드 조각은 counter 속성의 기본 시작 및 증분 값 사용을 보여줍니다.

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

정적 테이블 스키마 접근 방식이 다음 코드 조각에 나와 있습니다. 원자 카운터 확장은 시작 값 10을 사용하고 레코드가 기록될 때마다 값을 5씩 증가시킵니다.

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

를 사용하여 타임스탬프 추가 AutoGeneratedTimestampRecordExtension

AutoGeneratedTimestampRecordExtension 확장은 항목이 데이터베이스에 성공적으로 기록될 때마다 태그가 지정된 유형의 속성을 현재 타임스탬프Instant로 자동으로 업데이트합니다. 이 확장은 기본적으로 로드되지 않습니다.

구성

현재 타임스탬프로 업데이트할 속성을 지정하려면 테이블 스키마에서 Instant 속성에 태그를 지정하세요.

lastUpdate 속성은 다음 코드 조각에서 익스텐션 동작의 대상입니다. 속성이 Instant 유형이어야 한다는 요구 사항에 유의하세요.

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

동일한 정적 테이블 스키마 접근 방식이 다음 코드 조각에 나와 있습니다.

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

AutoGeneratedUuidExtension을 사용하여 UUID 생성

AutoGeneratedUuidExtension 확장은 새 레코드가 데이터베이스에 기록될 때 속성에 대한 고유한 UUID(Universally Unique Identifier)를 생성합니다. Java JDK UUID.randomUUID() 메서드를 사용하고 유형의 속성에 적용됩니다java.lang.String. 이 확장은 기본적으로 로드되지 않습니다.

구성

uniqueId 속성은 다음 코드 조각에서 익스텐션 동작의 대상입니다.

@AutoGeneratedUuidExtension public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

동일한 정적 테이블 스키마 접근 방식이 다음 코드 조각에 나와 있습니다.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())

확장이 putItem 메서드에 대해서만 UUID를 채우고 updateItem 메서드에 대해서는 채우지 않도록 하려면 다음 코드 조각과 같이 업데이트 동작 주석을 추가합니다.

@AutoGeneratedUuidExtension @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS) public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

정적 테이블 스키마 접근 방식을 사용하는 경우 다음과 같은 동등한 코드를 사용합니다.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(), StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))