executeTransactionPlan
Runs every step of plan in one transaction, in the order they were added, and returns what each produced.
A step's parameters are resolved just before it runs, so a TransactionValue pointing at an earlier step gets the value that step actually produced. Anything else in the map is passed through.
There is no …Result variant of this the way transactionResult is one of transaction, and the asymmetry has a reason: a block can return a failure, which is what a plain transaction would commit over, while a plan's steps can only throw. So dbResult { db.executeTransactionPlan(plan) } is both sufficient and correct.
Everything a step raises names that step on its path - resolving its parameters, running its statement, mapping its result alike - and is otherwise the exception the driver threw, so what is caught on and retried is unchanged. The number is where the step sits in the plan being run, which after TransactionPlan.addPlan is not the index its handle was created at; describe is what turns it back into a step.
Return
Every step's result, by handle.
Parameters
The steps to run.
What to do about a transaction already running on this thread.
The isolation level to run at, or null for the server's.
Whether the transaction refuses writes.
Aborts any single statement running longer than this.
Aborts the transaction once it has been open longer than this.
Throws
INVALID_ARGUMENT where a step's query cannot be rendered or a step binds a handle whose step is not ahead of it in this plan, both found before any step runs.