Search code examples
hyperledger-fabricpdc

Hyperledger fabric - Need two unique fields in private data collection


I am working on a scenario in private data collection where I want to have one more unique field other than ID. e.g. I have an object which contains carID, color, modelNumber fields of which I want carID as well as modelNumber to be unique. When I try to implement this I need to call getPrivateDataQueryResults() before adding new asset using putPrivateData() and I am getting error : Unsupported transaction: Transaction has already performed queries on pvt data. Writes are not allowed.

I expected a boolean response from getPrivateDataQueryResults() for modelNumber. If it is true, it should call putPrivateData() otherwise throw error like "Model number already exists".

But in response the error I am getting is "Unsupported transaction: Transaction has already performed queries on pvt data. Writes are not allowed."

Being new in HLFI am stuck on how to implement this scenario. Any help would be greatly appreciated.

Thanks in advance.


Solution

  • When I try to implement this I need to call getPrivateDataQueryResults() before adding new asset using putPrivateData() and I am getting error : Unsupported transaction: Transaction has already performed queries on pvt data. Writes are not allowed.

    I'm lazy so let me cite from the official documentation:

    Concurrency Control Version Check is a method of keeping ledger state in sync across peers on a channel. Peers execute transactions in parallel, and before committing to the ledger, peers check whether the state read at the time the transaction was executed has been modified in a new block that was in-flight at time of execution or in a prior transaction in the same block. If the data read for the transaction has changed between execution time and commit time, then a Concurrency Control Version Check violation has occurred, and the transaction is marked as invalid on the ledger and values are not updated in the state database.

    The above is true for regular GetState or range queries. However, rich queries are not re-executed upon commit time. This means that in order to protect the integrity of transaction execution (such that the end result of data changes is equivalent to some serial execution), if you used a rich query in your transaction, the transaction should not have any data updates. That's why you're getting your error.