Skip to content

Commit

Permalink
feat: add inline begin transaction for batch DML requests
Browse files Browse the repository at this point in the history
  • Loading branch information
ko3a4ok committed Sep 20, 2022
1 parent 154872b commit 2caaa0f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
15 changes: 13 additions & 2 deletions src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,7 @@ export class Snapshot extends EventEmitter {
*
* @param {spannerClient.spanner.v1.ITransaction} resp Response object.
*/
private _update(resp: spannerClient.spanner.v1.ITransaction): void {
protected _update(resp: spannerClient.spanner.v1.ITransaction): void {
const {id, readTimestamp} = resp;

this.id = id!;
Expand Down Expand Up @@ -1584,14 +1584,20 @@ export class Transaction extends Dml {
return {sql, params, paramTypes};
});

const transaction: spannerClient.spanner.v1.ITransactionSelector = {};
if (this.id) {
transaction.id = this.id as Uint8Array;
} else {
transaction.begin = this._options;
}
const reqOpts: spannerClient.spanner.v1.ExecuteBatchDmlRequest = {
session: this.session.formattedName_!,
requestOptions: this.configureTagOptions(
false,
this.requestOptions?.transactionTag ?? undefined,
(options as BatchUpdateOptions).requestOptions
),
transaction: {id: this.id!},
transaction,
seqno: this._seqno++,
statements,
} as spannerClient.spanner.v1.ExecuteBatchDmlRequest;
Expand All @@ -1618,6 +1624,11 @@ export class Transaction extends Dml {
}

const {resultSets, status} = resp;
for (const resultSet of resultSets) {
if (!this.id && resultSet.metadata && resultSet.metadata.transaction) {
this._update(resultSet.metadata.transaction);
}
}
const rowCounts: number[] = resultSets.map(({stats}) => {
return (
(stats &&
Expand Down
18 changes: 16 additions & 2 deletions test/mockserver/mockspanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ export class MockSpanner {
this.pushRequest(call.request!, call.metadata);
this.simulateExecutionTime(this.executeBatchDml.name)
.then(() => {
if (call.request!.transaction && call.request!.transaction.id) {
if (call.request!.transaction) {
const fullTransactionId = `${call.request!.session}/transactions/${
call.request!.transaction.id
}`;
Expand Down Expand Up @@ -764,7 +764,21 @@ export class MockSpanner {
callback(new Error('Wrong result type for batch DML'));
break;
case StatementResultType.UPDATE_COUNT:
results.push(MockSpanner.toResultSet(res.updateCount));
let resultSet = MockSpanner.toResultSet(res.updateCount);
if (call.request!.transaction!.begin && i === 0) {
const transaction = this._updateTransaction(
call.request!.session,
call.request?.transaction!.begin
);
if (transaction instanceof Error) {
callback(transaction);
break;
}
resultSet.metadata = protobuf.ResultSetMetadata.create({
transaction
});
}
results.push(resultSet);
break;
case StatementResultType.ERROR:
if ((res.error as grpc.ServiceError).code) {
Expand Down
8 changes: 8 additions & 0 deletions test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ describe('Spanner with mock server', () => {
requestTag: 'request-tag',
},
});
await tx!.batchUpdate([insertSql, insertSql]);
return await tx.commit();
}
);
Expand All @@ -307,6 +308,13 @@ describe('Spanner with mock server', () => {
request.requestOptions!.transactionTag,
'transaction-tag'
);
assert.ok(request.transaction?.begin, 'transaction is not empty');
const nextBatchRequest = spannerMock.getRequests().reverse().find(val => {
return (val as v1.ExecuteBatchDmlRequest).statements;
}) as v1.ExecuteBatchDmlRequest;
assert.ok(nextBatchRequest, 'no ExecuteBatchDmlRequest found');
assert.ok(nextBatchRequest.transaction?.id, 'no transaction ID');

const commitRequest = spannerMock.getRequests().find(val => {
return (val as v1.CommitRequest).mutations;
}) as v1.CommitRequest;
Expand Down

0 comments on commit 2caaa0f

Please sign in to comment.