# 두 번째 완료가 비교하는 것
261:    if (row.state() == IdempotencyState.COMPLETED
262:        && "COMPLETE".equals(row.lastTransitionKind())
263:        && operationId.value().equals(row.lastTransitionOperationId())) {
264:      return responseDigest.equals(row.responseDigest())
265:          ? IdempotencyCompleteOutcome.ALREADY_COMPLETED_SAME_RESULT
266:          : IdempotencyCompleteOutcome.RESPONSE_CONFLICT;
267:    }
268:    IdempotencyCompleteOutcome mismatch = classifyCompleteMismatch(row, owner);

# 첫 완료가 다이제스트에 넣는 것과 그 이유 주석
274:            owner,
275:            operationId.value(),
276:            // The transition digest, not the response digest. Reusing the response digest here made
277:            // two completions of different operations with identical payloads indistinguishable,
278:            // and lost the replay window the completion also decided.
279:            transitionDigest(
280:                "COMPLETE",
281:                operationId,
282:                owner,
283:                responseDigest,
284:                Long.toString(replayTtl.toMillis())),
285:            response.payload(),

# 공용 헬퍼와 그것이 읽는 열
557:  private static ReplayVerdict replayVerdict(
558-      IdempotencyRecordRow row,
559-      String transitionKind,
560-      OperationId operationId,
561-      String expectedDigest) {
562-    if (!transitionKind.equals(row.lastTransitionKind())
563-        || !operationId.value().equals(row.lastTransitionOperationId())) {
564-      return ReplayVerdict.NOT_A_REPLAY;
565-    }
566-    return expectedDigest.equals(row.lastTransitionResultDigest())
567-        ? ReplayVerdict.SAME_ARGUMENTS
568-        : ReplayVerdict.DIFFERENT_ARGUMENTS;
569-  }
570-
27:    String lastTransitionOperationId,
28:    String lastTransitionKind,
29:    String lastTransitionResultDigest,
58:    ADD COLUMN IF NOT EXISTS last_transition_result_digest char(64),

# 그 헬퍼를 쓰는 네 전이
  182:    switch (replayVerdict(row, "START", operationId, startDigest)) {
  221:    switch (replayVerdict(row, "RENEW", operationId, renewDigest)) {
  319:    switch (replayVerdict(row, transitionKind, operationId, failDigest)) {
  366:    switch (replayVerdict(row, "RELEASE", operationId, releaseDigest)) {
#   complete 본문에서 그것을 부르는 줄: 0

# 값이 다르다는 것은 이미 단위 시험이 고정한다
39:  void twoCompletionsWithDifferentReplayWindowsDiffer() {
40-    assertThat(IdempotencyDigestPolicy.of("COMPLETE", "op-1", "owner-1", 1, 3, "digest-a", "60000"))
41-        .isNotEqualTo(
42-            IdempotencyDigestPolicy.of("COMPLETE", "op-1", "owner-1", 1, 3, "digest-a", "90000"));
43-  }

# 갱신 경로의 주석
216:    // The lease TTL is part of what a renewal decided, so it is part of the digest. Without it, a
217:    // retry asking for a different lease was confirmed as the renewal already applied, and the
218:    // caller went on believing it held the record for longer than the row says it does.

# 출하 통합 시험이 덮는 인자 재생
256:  void aRetriedFailureWithTheSameArgumentsIsConfirmedRatherThanAppliedTwice() {
281:  void aFailureRepeatedUnderOneOperationIdWithDifferentRetentionIsAConflict() {
315:  void aRenewalRepeatedUnderOneOperationIdWithADifferentLeaseIsAConflict() {
#   그 파일에서 완료를 부르는 곳: 2
#   ALREADY_COMPLETED_SAME_RESULT 를 단언하는 곳: 0

# 레디스 구현도 같은 자리에서 멈춘다
231:        case "ALREADY" ->
232-            // The same owner completing twice. Whether it is the same result decides whether this
233-            // is an idempotent repeat or a contradiction the caller has to see.
234-            reply.payload().equals(response.payload())
235-                ? IdempotencyCompleteOutcome.ALREADY_COMPLETED_SAME_RESULT
236-                : IdempotencyCompleteOutcome.RESPONSE_CONFLICT;
--
291:        case "ALREADY" -> IdempotencyFailOutcome.ALREADY_MARKED_SAME_OPERATION;
113:        return {'ALREADY', attempt, rev, owner, redis.call('HGET', KEYS[1], 'resp') or '', ''}
130:      if ARGV[8] ~= '' then
