Aws-sdk-php: transactWriteItems returns An unknown operation was requested

Created on 6 Dec 2018  路  13Comments  路  Source: aws/aws-sdk-php

Hi, I'm trying to create a transaction with DynamoDb,
I have tried this:

$data = [
            'id' => Uuid::uuid4()->toString(),
            'uuid' => $domainMessage->getId(),
            'playhead' => $domainMessage->getPlayhead(),
            'metadata' => json_encode($this->metadataSerializer->serialize($domainMessage->getMetadata())),
            'payload' => json_encode($this->payloadSerializer->serialize($domainMessage->getPayload())),
            'recorded_on' => $domainMessage->getRecordedOn()->toString(),
            'type' => $domainMessage->getType(),
        ];

        $marshal = new Marshaler();
        $data = $marshal->marshalJson(json_encode($data));

$this->client->transactWriteItems([
                'TransactItems' => [
                    [
                        'Put' => [
                            'TableName' => $this->table,
                            'Item' => $data
                        ]
                    ]
                ]
            ]
        );

But returns me this error:

Aws\DynamoDb\Exception\DynamoDbException: Error executing "TransactWriteItems" on "http://localhost:8000"; AWS HTTP error: Client error: `POST http://localhost:8000` resulted in a `400 Bad Request` response:
{"__type":"com.amazonaws.dynamodb.v20120810#UnknownOperationException","message":"An unknown operation was requested."}
 UnknownOperationException (client): An unknown operation was requested. - {"__type":"com.amazonaws.dynamodb.v20120810#UnknownOperationException","message":"An unknown operation was requested."}

If I make a simple putItems with same data it's ok, What I miss or what is the error?

feature-request service-api

Most helpful comment

Thanks to everyone involved in the thread for your patience and feedback on this! The DynamoDB team responded to my internal request today stating that they are actively working on an update for DynamoDB Local that implements support for Transactions API calls. While they unfortunately do not have a release date for this update, it should be available fairly soon.

All 13 comments

Hi @AlessandroMinoccheri, in order for us to better troubleshoot this behavior can you provide the version of the AWS SDK for PHP that you are using, along with debug output when attempting this call? You can enable debug logging by setting 'debug' => true, in the DynamoDB client configuration options.

With debug mode there are a lot of info, I think that this could be useful:

error was set to array(13) {
    ["instance"]=>
    string(32) "000000007c825275000000003199846f"
    ["class"]=>
    string(40) "Aws\DynamoDb\Exception\DynamoDbException"
    ["message"]=>
    string(480) "Error executing "TransactWriteItems" on "http://localhost:8000"; AWS HTTP error: Client error: `POST http://localhost:8000` resulted in a `400 Bad Request` response:
  {"__type":"com.amazonaws.dynamodb.v20120810#UnknownOperationException","message":"An unknown operation was requested."}
   UnknownOperationException (client): An unknown operation was requested. - {"__type":"com.amazonaws.dynamodb.v20120810#UnknownOperationException","message":"An unknown operation was requested."}"
    ["file"]=>
    string(101) "/Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php"
    ["line"]=>
    int(191)
    ["trace"]=>
    string(4430) "#0 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php(100): Aws\WrappedHttpHandler->parseError(Array, Object(GuzzleHttp\Psr7\Request), Object(Aws\Command), Array)
  #1 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(203): Aws\WrappedHttpHandler->Aws\{closure}(Array)
  #2 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(174): GuzzleHttp\Promise\Promise::callHandler(2, Array, Array)
  #3 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/RejectedPromise.php(40): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}(Array)
  #4 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/TaskQueue.php(47): GuzzleHttp\Promise\RejectedPromise::GuzzleHttp\Promise\{closure}()
  #5 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(98): GuzzleHttp\Promise\TaskQueue->run()
  #6 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(125): GuzzleHttp\Handler\CurlMultiHandler->tick()
  #7 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
  #8 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
  #9 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
  #10 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
  #11 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
  #12 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
  #13 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
  #14 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(58): GuzzleHttp\Promise\Promise->wait()
  #15 /Users/alessandrominoccheri/Sites/broadway-dynamodb/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(77): Aws\AwsClient->execute(Object(Aws\Command))
  #16 /Users/alessandrominoccheri/Sites/broadway-dynamodb/src/DynamoDbEventStore.php(166): Aws\AwsClient->__call('transactWriteIt...', Array)
  #17 /Users/alessandrominoccheri/Sites/broadway-dynamodb/src/DynamoDbEventStore.php(142): Broadway\EventStore\DynamoDb\DynamoDbEventStore->insertMessage(Object(Broadway\Domain\DomainMessage))
  #18 /Users/alessandrominoccheri/Sites/broadway-dynamodb/test/DynamoDbEventStoreTest.php(175): Broadway\EventStore\DynamoDb\DynamoDbEventStore->append('e238fe34-60df-4...', Object(Broadway\Domain\DomainEventStream))
  #19 [internal function]: Tests\DynamoDbEventStoreTest->testInsertMessageAndVisitEvents()
  #20 phar:///usr/local/bin/phpunit/phpunit/Framework/TestCase.php(1120): ReflectionMethod->invokeArgs(Object(Tests\DynamoDbEventStoreTest), Array)
  #21 phar:///usr/local/bin/phpunit/phpunit/Framework/TestCase.php(971): PHPUnit_Framework_TestCase->runTest()
  #22 phar:///usr/local/bin/phpunit/phpunit/Framework/TestResult.php(709): PHPUnit_Framework_TestCase->runBare()
  #23 phar:///usr/local/bin/phpunit/phpunit/Framework/TestCase.php(926): PHPUnit_Framework_TestResult->run(Object(Tests\DynamoDbEventStoreTest))
  #24 phar:///usr/local/bin/phpunit/phpunit/Framework/TestSuite.php(728): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
  #25 phar:///usr/local/bin/phpunit/phpunit/Framework/TestSuite.php(728): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
  #26 phar:///usr/local/bin/phpunit/phpunit/TextUI/TestRunner.php(521): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
  #27 phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array, true)
  #28 phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php(118): PHPUnit_TextUI_Command->run(Array, true)
  #29 /usr/local/bin/phpunit(583): PHPUnit_TextUI_Command::main()
  #30 {main}"
    ["type"]=>
    string(6) "client"
    ["code"]=>
    string(25) "UnknownOperationException"
    ["requestId"]=>
    string(36) "924c41b7-9367-4d2b-ae0e-185b42130264"
    ["statusCode"]=>
    int(400)
    ["result"]=>
    NULL
    ["request"]=>
    array(6) {
      ["instance"]=>
      string(32) "000000007c8253a7000000003199846f"
      ["method"]=>
      string(4) "POST"
      ["headers"]=>
      array(9) {
        ["X-Amz-Security-Token"]=>
        string(7) "[TOKEN]"
        ["Host"]=>
        array(1) {
          [0]=>
          string(14) "localhost:8000"
        }
        ["X-Amz-Target"]=>
        array(1) {
          [0]=>
          string(36) "DynamoDB_20120810.TransactWriteItems"
        }
        ["Content-Type"]=>
        array(1) {
          [0]=>
          string(26) "application/x-amz-json-1.0"
        }
        ["User-Agent"]=>
        array(1) {
          [0]=>
          string(18) "aws-sdk-php/3.80.2"
        }
        ["aws-sdk-invocation-id"]=>
        array(1) {
          [0]=>
          string(32) "XXX"
        }
        ["aws-sdk-retry"]=>
        array(1) {
          [0]=>
          string(3) "0/0"
        }
        ["X-Amz-Date"]=>
        array(1) {
          [0]=>
          string(16) "20181209T211315Z"
        }
        ["Authorization"]=>
        array(1) {
          [0]=>
          string(203) "AWS4-HMAC-SHA256 Credential=not-a-real-key/20181209/us-west-2/dynamodb/aws4_request, SignedHeaders=host;x-amz-date;x-amz-target, Signature=[SIGNATURE]
        }
      }
      ["body"]=>
      string(784) "{"TransactItems":[{"Put":{"TableName":"dynamo_table","Item":{"id":{"S":"67b74020-7199-4b51-8895-ecd9d9f2d7b9"},"uuid":{"S":"e238fe34-60df-4980-8797-6294cbc5840e"},"playhead":{"N":"4065"},"metadata":{"S":"{\"class\":\"Broadway\\\\Domain\\\\Metadata\",\"payload\":{\"values\":{\"id\":\"e238fe34-60df-4980-8797-6294cbc5840e\",\"foo\":\"bar\"}}}"},"payload":{"S":"{\"class\":\"class@anonymous\\u0000\\\/Users\\\/alessandrominoccheri\\\/Sites\\\/broadway-dynamodb\\\/test\\\/DynamoDbEventStoreTest.php0x1109ed254\",\"payload\":[]}"},"recorded_on":{"S":"2018-12-09T21:13:15.997248+00:00"},"type":{"S":"class@anonymous\u0000\/Users\/alessandrominoccheri\/Sites\/broadway-dynamodb\/test\/DynamoDbEventStoreTest.php0x1109ed254"}}}}],"ClientRequestToken":"e741f91e-8b5e-4923-b57b-5aa49eb0aa5b"}"
      ["scheme"]=>
      string(4) "http"
      ["port"]=>
      int(8000)
    }
    ["response"]=>
    array(4) {
      ["instance"]=>
      string(32) "000000007c82539c000000003199846f"
      ["statusCode"]=>
      int(400)
      ["headers"]=>
      array(5) {
        ["X-Amz-Security-Token"]=>
        string(7) "[TOKEN]"
        ["Content-Type"]=>
        array(1) {
          [0]=>
          string(26) "application/x-amz-json-1.0"
        }
        ["x-amzn-RequestId"]=>
        array(1) {
          [0]=>
          string(36) "924c41b7-9367-4d2b-ae0e-185b42130264"
        }
        ["Content-Length"]=>
        array(1) {
          [0]=>
          string(3) "119"
        }
        ["Server"]=>
        array(1) {
          [0]=>
          string(23) "Jetty(8.1.12.v20130726)"
        }
      }
      ["body"]=>
      string(119) "{"__type":"com.amazonaws.dynamodb.v20120810#UnknownOperationException","message":"An unknown operation was requested."}"
    }
  }

  Inclusive step time: 0.016627073287964

Thanks for the additional info. The User-Agent value shows you're using version 3.80.2 of the AWS SDK for PHP, which should definitely support executing DynamoDB's TransactWriteItems API call. Can you try updating the SDK, either via Composer or using the phar/zip files in our releases page, to see if you continue receiving this error?

I have update version to 3.81.3 but the error still the same

Looking more closely at the error response in your initial post I see that you're running this against a local instance of DynamoDB rather than a DynamoDB endpoint in AWS. It is possible that your local version of DynamoDB is not new enough to support TransactWriteItems, or that the local version of DynamoDB has not yet had an update to include this API call.

Can you try running this call against a DynamoDB table that exists in AWS rather than on your local host to rule out the AWS SDK for PHP as the culprit for this behavior? If this call doesn't work on an AWS endpoint you should check the API model for DynamoDB on your local copy of the SDK to ensure it includes the TransactWriteItems API, this can be found in the file src/data/dynamodb/2012-08-10/api-2.json in your SDK directory.

I'm using this docker and I think is not updated with Transaction

https://hub.docker.com/r/amazon/dynamodb-local/

I need to wait a new docker or there is a new updated version?

My team is also using the docker hub image (linked above) for local development. Any timeline for when that image will be updated to support transactions? Thanks!

@AlessandroMinoccheri @bcdxn Thanks for the additional information & feedback on this! I've reached out to the DynamoDB team internally asking for a status and timeline on updating the DynamoDB Local Docker container to support Transactions, once I have more info on this I'll update the issue accordingly.

Thanks to everyone involved in the thread for your patience and feedback on this! The DynamoDB team responded to my internal request today stating that they are actively working on an update for DynamoDB Local that implements support for Transactions API calls. While they unfortunately do not have a release date for this update, it should be available fairly soon.

Any update on this? I hit the same error today

@purefan thanks for checking in on this. The DynamoDB team released an update for DynamoDB Local in February that supports transactional APIs. I downloaded the latest version of the dynamodb-local docker container this morning and was able to create a table and issue a TransactWriteItems call to my local DynamoDB instance with a successful response.

If you are still seeing an UnknownOperationException response from your local DynamoDB installation / docker container when executing transactional API calls you may want to try updating to a newer version of DynamoDB Local to see if you still run into this.

Oh! thanks for the reply @diehlaws ! I guess that must be it, my docker dynamodb is 10 months old :P

Edit: Yeap, that was it... just an old docker image... Thanks for the help!

I'm glad to hear updating your DynamoDB Docker container did the trick! I think we can consider this issue solved and close it out.

Was this page helpful?
0 / 5 - 0 ratings