使用php在AWS QLDB中提交事务时如何获取/计算CommitDigest?

问题描述

每当我尝试提交交易时。它给出一个错误摘要应为32字节,我尝试提交摘要的二进制值,然后给出 提交摘要与qldb(分类帐)摘要不匹配的错误

    public function insert()
{
    $client = AwsFacade::createClient('qldb-session');
    $clientA = AwsFacade::createClient('qldb');
    $result = $client->sendCommand([
        'StartSession' => [
            'LedgerName' => 'LawHq',],]);
    $sessiontoken = ((object)$result->get('StartSession'))->SessionToken;
    
    $result = $client->sendCommand([
        'StartTransaction' =>
        [],'SessionToken' => $sessiontoken
    ]);
    $transectiontoken = ((object)$result->get('StartTransaction'))->TransactionId;
    $result = $client->sendCommand([
        'ExecuteStatement' => [
            'Statement' => 'INSERT INTO Employee {`Name`:`wow`,`Designation`:`ok`,`Address`:`hmm`}','TransactionId' => $transectiontoken,'SessionToken' => $sessiontoken
    ]);
    $result = $clientA->getDigest([
        'Name' => 'LawHq',]);
    $digest = $result->get("Digest");
    $diges = base64_encode($result->get("Digest"));
    $result = $client->sendCommand([
        'CommitTransaction' => [
            'CommitDigest' => $digest,'TransactionId' => $transectiontoken
        ],'SessionToken' => $sessiontoken
    ]);
}

解决方法

您通过$clientA->getDigest(['Name' => 'LawHq']);获得的摘要是分类帐的摘要,与CommitDigest不同。您可以了解有关账本摘要here的更多信息。

该机制以下列方式工作:对于每个事务(可以包含多个PartiQL语句),客户端必须计算CommitDigest(使用下面提到的算法)。同时,QLDB在服务器端还使用相同的算法计算CommitDigest。然后,当您决定提交事务时,必须将CommitDigest传递给QLDB(通过CommitTransaction API)。如果您传递的CommitDigest与计算的CommitDigest QLDB相同,则您的事务将被提交(假设没有其他错误),否则QLDB将拒绝您的事务。

CommitDigest计算依赖于计算IonHash的能力。计算IonHash并非易事,通常是由IonHash库完成的。不幸的是,没有用于PHP的IonHash库。如果您希望自己实现,则可以查看IonHash规范https://amzn.github.io/ion-hash/docs/spec.html作为计算IonHash的起点。一旦有了一种计算IonHash的方法,就可以实现该算法来计算CommitDigest,类似于其他QLDB驱动程序所做的。

当QLDB没有Node.js驱动程序时,Marc概述了CommitDigest和算法的动机:How to get/compute CommitDigest when committing a transaction in AWS QLDB?

我鼓励您阅读他的完整答案以获取更多背景信息。引用他的答案中的相关片段

该算法也非常简单:将哈希值填充到交易ID中,然后使用QLDB“点”运算符进行更新。语句哈希(PartiQL字符串的sha256)以及所有绑定值的IonHash中的每个更新“点”。点运算符是QLDB合并哈希值的方式(与验证API中使用的运算符相同),并被定义为两个哈希值的并置哈希值,按(有符号,little-endian)按字节顺序比较在两个哈希之间。客户端和服务器以锁定步骤运行此算法,并且仅当客户端传递的值与服务器计算的值匹配时,服务器才会处理commit命令。这样,服务器将永远不会提交与客户要求不完全相同的交易。

请注意,当Marc编写答案时,尽管没有QLDB的Node.js驱动程序,但ion-hash-js库可用,而PHP则不是。

或者,如果可能的话,我强烈建议使用现有的驱动程序之一,因为它可以轻松地与QLDB进行交互。这些驱动程序在PythonNodejsJava.NetGolang(in preview)中可用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...