public CompletionStage<Void> updateTransactionallyAsync(final Account account,
      final Collection<TransactWriteItem> additionalWriteItems) {

    return AsyncTimerUtil.record(UPDATE_TRANSACTIONALLY_TIMER, () -> {
      final List<TransactWriteItem> writeItems = new ArrayList<>(additionalWriteItems.size() + 1);
      writeItems.add(UpdateAccountSpec.forAccount(accountsTableName, account).transactItem());
      writeItems.addAll(additionalWriteItems);

      return asyncClient.transactWriteItems(TransactWriteItemsRequest.builder()
              .transactItems(writeItems)
              .build())
          .thenApply(response -> {
            account.setVersion(account.getVersion() + 1);
            return (Void) null;
          })
          .exceptionally(throwable -> {
            final Throwable unwrapped = ExceptionUtils.unwrap(throwable);

            if (unwrapped instanceof TransactionCanceledException transactionCanceledException) {
              if (CONDITIONAL_CHECK_FAILED.equals(transactionCanceledException.cancellationReasons().get(0).code())) {
                throw new ContestedOptimisticLockException();
              }

              if (transactionCanceledException.cancellationReasons()
                  .stream()
                  .anyMatch(reason -> TRANSACTION_CONFLICT.equals(reason.code()))) {

                throw new ContestedOptimisticLockException();
              }
            }

            throw CompletableFutureUtils.errorAsCompletionException(throwable);
          });
    });
  }
@Test
  void testUpdateTransactionallyContestedLock() {
    final Account account = generateAccount("+14151112222", UUID.randomUUID(), UUID.randomUUID());
    createAccount(account);

    account.setVersion(account.getVersion() - 1);

    final CompletionException completionException = assertThrows(CompletionException.class,
        () -> accounts.updateTransactionallyAsync(account, List.of(TransactWriteItem.builder()
            .put(Put.builder()
                .tableName(Tables.CLIENT_RELEASES.tableName())
                .item(Map.of(
                    ClientReleases.ATTR_PLATFORM, AttributeValues.fromString("test"),
                    ClientReleases.ATTR_VERSION, AttributeValues.fromString("test")
                ))
                .build())
            .build())).toCompletableFuture().join());

    assertTrue(completionException.getCause() instanceof ContestedOptimisticLockException);
  }