Go#6이 있는 DynamoDB - 트랜잭션이 있는 레거시 ID 매핑
Previous approach
이 문제의 초기 해결 방안은 남겨진 id에 새 id를 생성하고 DB에 비추는 것입니다.조건에 의하면, 만약 남겨진 id에 대한 맵이 존재한다면, 우리는 이렇게 하기를 원하지 않습니다.조건이 성공했을 때, 우리는 주어진 남겨진 id가 아직 비치지 않았고, 비치는 다이나믹 DB에 삽입되었다는 것을 안다.그러나 조건이 실패하면 맵이 존재한다는 것을 알고 데이터베이스에서 가져와야 합니다.
이런 방법은 데이터 경쟁의 영향을 받지 않고 매우 잘 일한다.주어진 id를 처음으로 호출하기 위해서
Map
함수를 호출할 때, 다이나마이트에 대한 호출이 필요합니다.조건이 성공하면 새로 생성된 id를 되돌려줍니다. 단, 같은 id를 사용하여 Map
후속 호출을 하려면 데이터베이스에 두 번 호출해야 합니다.첫 번째는 우리의 조건 때문에 실패한 호출이고, 두 번째는 다이나모에서 이미 존재하는 새로운 id를 가져옵니다.ReturnValues parameter
사실이 증명하듯이
PutItem
중의 매개 변수는 ReturnValues
라고 한다.기본값NONE
또는 ALL_OLD
로 설정할 수 있습니다.ALL_OLD
는 PutItem
가 항목을 덮어쓰면 다이나마이트에서 온 응답이 덮어쓰기 전에 내용을 포함한다는 것을 나타낸다.이것은 우리에게 있어서 매우 좋다.우리는 만약 우리가 실패한다면, 무엇이 실패를 초래했는지 알고 싶다.이것은 우리가 두 번째로 디나모에게 전화할 필요가 없다는 것을 의미한다.불행하게도
PutItem
성공하고 조건 검사에 실패한 경우 PutItem
실패하기 전에 프로젝트의 이미지를 얻을 수 없을 때만 유효합니다.이것은 작용하지 않기 때문이다. 아마도 우리가 얻은 조건 실패에 대한 오류는 왜 실패했는지에 대한 상하문을 더 많이 포함하고 있을 것이다.
불행히도 사실은 그렇지 않다.
그러나 우리는 다른 곳에서 이 아이디어를 사용해서 우리가 원하는 것을 얻을 수 있다.
Transactions
일반적으로 거래는 다른 목적을 위한 것이다.데이터베이스 상태에 대한 많은 변경이 필요하고 모든 변경이 성공해야만 업무를 완성할 수 있을 때 사용할 수 있습니다.만약 업무 중의 변경 사항이 실패하면 전체 업무가 실패하고 아무런 변경도 하지 않습니다.
트랜잭션이 실패하면 DynamoDB는 어떤 일이 일어났는지 더 많은 상하문을 제공할 수 있습니다.그것이 어떻게 일을 하는지 우리에게 보여 주시오.
Code
모든 코드는 5회 코드와 같다.유일하게 변경된 기능은
Map
기능입니다.여기서는 행위만 검증하는 자동화 테스트의 묘미를 볼 수 있다.우리는 마음대로 변경할 수 있어, 테스트는 전혀 변경할 필요가 없다.그 밖에 그들은 우리에게 새로운 방법이 효과가 있는지의 여부를 알려줄 것이다.사무를 사용하기 위해
Map
함수를 변경합시다.idsMapping := mapping{OldID: old, NewID: uuid.New().String()}
attrs, err := dynamodbattribute.MarshalMap(&idsMapping)
if err != nil {
return "", err
}
expr, err := expression.NewBuilder().
WithCondition(expression.AttributeNotExists(expression.Name("old_id"))).
Build()
if err != nil {
return "", err
}
내가 너에게 Map
개의 기능만 바뀌었다고 말했을 때, 나는 결코 전부를 가리키는 것이 아니다.시작이 똑같다.간단하게 돌이켜 보면, 우리가 생성한 낡은 id와 새 id를 사용하여 맵을 만듭니다.그리고 우리가 이미 존재하는 항목을 놓으려고 할 때, 우리는 실패의 조건을 만들었다._, err = m.db.TransactWriteItemsWithContext(ctx, &dynamodb.TransactWriteItemsInput{
TransactItems: []*dynamodb.TransactWriteItem{
{
Put: &dynamodb.Put{
ConditionExpression: expr.Condition(),
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
Item: attrs,
ReturnValuesOnConditionCheckFailure: aws.String("ALL_OLD"),
TableName: aws.String(m.table),
},
},
},
})
여기 주문서Put
가 조작된 거래가 있습니다.일반적인 PutItem
방법인 ReturnValuesOnConditionCheckFailure
매개 변수의 옵션이 아닌 것도 있다.조건이 실패할 때, 우리가 원하는, 즉 이미 존재하는 새로운 id를 얻을 수 있기를 바랍니다.이곳의 관건은 잘못된 처리다.
if err == nil {
return idsMapping.NewID, nil
}
오류가 없으면 조건이 성공했다는 것을 의미합니다. 따라서 주어진 유류 id 호출 Map
을 사용한 것은 이번이 처음입니다. 다이나마이드에 입력한 내용만 되돌려줍니다.aerr, ok := err.(*dynamodb.TransactionCanceledException)
if !ok {
return "", err
}
만약 오류가 있다면, 우리는 그것의 유형을 검사해야 한다. 만약 TransactionCanceledException
그렇지 않다면, 문제가 생겼을 것이다. 우리는 그것이 무엇인지 모르기 때문에, 우리는 되돌아갈 뿐이다.return aws.StringValue(aerr.CancellationReasons[0].Item["new_id"].S), nil
그렇지 않으면 new_id
로부터 CancellationReasons
를 받을 수 있습니다. 우리는 그것을 고객에게 되돌려줄 수 있습니다. 디나모에게 다시 전화할 필요가 없습니다!Summary
DynamoDB API를 사용하여 트랜잭션이 실패한 이유를 설명하는 방법을 방금 설명했습니다.예를 들어 DynamoDB에 새로운 맵을 삽입하거나 기존 맵을 한꺼번에 얻을 수 있음을 의미합니다.
당신은 반드시 이런 방법을 사용해야 합니까?저번보다 좋아요?이것은 상황을 보고 결정해야 한다.DynamoDB를 한 번만 호출할 때 요청/응답 왕복 시간을 절약할 수 있습니다.그것은 공짜입니까?절대 아니야.당신이 지불할 용량 단위로 말하자면, 다이나모FB의 업무 호출은 더욱 비싸다.따라서 이러한 특수한 상황에서 DynamoDB 사무 호출에 더 많은 비용을 지불하든지, 보통 더 적은 호출을 하든지, 한 호출에 더 적은 비용을 지불하든지, 여러 번 DynamoDB를 호출하든지, 그리고 DynamoDB의 네트워크 호출을 기다리는 데 더 많은 시간을 들일 것이다.그럼에도 불구하고 나는 어떤 방법도 추천하지 않는다.이것은 너의 필요에 달려 있다.나는 단지 가능한 선택을 보여주고 있을 뿐이다.
Reference
이 문제에 관하여(Go#6이 있는 DynamoDB - 트랜잭션이 있는 레거시 ID 매핑), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jbszczepaniak/dynamodb-with-go-6-legacy-ids-mapping-with-transactions-1696텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)