Skip to content

Commit

Permalink
feat: optimisticLock option for getTransaction method (#2028)
Browse files Browse the repository at this point in the history
* feat: add option for optimistic lock in getTransaction method

* feat: add option for optimistic lock in getTransaction method

* add sample for read and write transaction

* add sample for read and write transaction

* chore: add integration test for the read/write query samples

* fix: presubmit error

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* fix: presubmit error

* refactor: sample doc

* refactor: sample doc

* refator: getTransaction method

* fix: lint errors

* fix: lint errors

* refactor: remove logs

* fix: presubmit error

* fix: lint errors

* test: add a unit test for getTransaction

* tests: add integration and unit test for getTransaction options properties

* fix: lint errors

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* refactor: naming convention for varaible in getTransaction method

* refactor: naming convention for varaible in getTransaction method

* fix: lint errors

* fix: lint error

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
alkatrivedi and gcf-owl-bot[bot] committed Apr 17, 2024
1 parent 5292e03 commit dacf869
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ system-test/*key.json
.DS_Store
package-lock.json
__pycache__
.vscode
31 changes: 29 additions & 2 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,13 @@ export interface GetIamPolicyOptions {
gaxOptions?: CallOptions;
}

/**
* @typedef {object} GetTransactionOptions
* * @property {boolean} [optimisticLock] The optimistic lock a
* {@link Transaction} should use while running.
*/
export type GetTransactionOptions = Omit<RunTransactionOptions, 'timeout'>;

export type CreateSessionCallback = ResourceCallback<
Session,
spannerClient.spanner.v1.ISession
Expand Down Expand Up @@ -1989,16 +1996,36 @@ class Database extends common.GrpcServiceObject {
* });
* ```
*/
getTransaction(): Promise<[Transaction]>;
getTransaction(
optionsOrCallback?: GetTransactionOptions
): Promise<[Transaction]>;
getTransaction(callback: GetTransactionCallback): void;
getTransaction(
optionsOrCallback?: GetTransactionOptions | GetTransactionCallback,
callback?: GetTransactionCallback
): void | Promise<[Transaction]> {
const cb =
typeof optionsOrCallback === 'function'
? (optionsOrCallback as GetTransactionCallback)
: callback;
const options =
typeof optionsOrCallback === 'object' && optionsOrCallback
? (optionsOrCallback as GetTransactionOptions)
: {};
this.pool_.getSession((err, session, transaction) => {
if (options.requestOptions) {
transaction!.requestOptions = Object.assign(
transaction!.requestOptions || {},
options.requestOptions
);
}
if (options.optimisticLock) {
transaction!.useOptimisticLock();
}
if (!err) {
this._releaseOnEnd(session!, transaction!);
}
callback!(err as grpc.ServiceError | null, transaction);
cb!(err as grpc.ServiceError | null, transaction);
});
}

Expand Down
18 changes: 18 additions & 0 deletions system-test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8894,6 +8894,24 @@ describe('Spanner', () => {
mismatchedColumnError(done, DATABASE, googleSqlTable);
});

it('GOOGLE_STANDARD_SQL should use getTransaction for executing sql', async () => {
const transaction = (
await DATABASE.getTransaction({optimisticLock: true})
)[0];

try {
const [rows] = await transaction!.run('SELECT * FROM TxnTable');
assert.strictEqual(rows.length, googleSqlRecords.length);
} catch (err) {
// flaky failures are acceptable here as long as the error is not due to a lock conflict
if ((err as grpc.ServiceError).code === grpc.status.ABORTED) {
assert.ok(err, 'Transaction is aborted');
}
} finally {
transaction.end();
}
});

it('POSTGRESQL should throw an error for mismatched columns', function (done) {
if (IS_EMULATOR_ENABLED) {
this.skip();
Expand Down
23 changes: 23 additions & 0 deletions test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3286,6 +3286,29 @@ describe('Spanner with mock server', () => {
});
});

it('should use optimistic lock and transaction tag for getTransaction', async () => {
const database = newTestDatabase();
const promise = await database.getTransaction({
optimisticLock: true,
requestOptions: {transactionTag: 'transaction-tag'},
});
const transaction = promise[0];
await transaction.run('SELECT 1').then(results => {

Check warning on line 3296 in test/spanner.ts

View workflow job for this annotation

GitHub Actions / lint

'results' is defined but never used
const request = spannerMock.getRequests().find(val => {
return (val as v1.ExecuteSqlRequest).sql;
}) as v1.ExecuteSqlRequest;
assert.ok(request, 'no ExecuteSqlRequest found');
assert.strictEqual(
request.transaction!.begin!.readWrite!.readLockMode,
'OPTIMISTIC'
);
assert.strictEqual(
request.requestOptions?.transactionTag,
'transaction-tag'
);
});
});

it('should reuse a session for optimistic and pessimistic locks', async () => {
const database = newTestDatabase({min: 1, max: 1});
let session1;
Expand Down

0 comments on commit dacf869

Please sign in to comment.