Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimisticLock option for getTransaction method #2028

Merged
merged 25 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fcfe1ab
feat: add option for optimistic lock in getTransaction method
alkatrivedi Apr 4, 2024
b901522
feat: add option for optimistic lock in getTransaction method
alkatrivedi Apr 4, 2024
c8d7f40
add sample for read and write transaction
alkatrivedi Apr 5, 2024
b201049
add sample for read and write transaction
alkatrivedi Apr 5, 2024
5a638d7
chore: add integration test for the read/write query samples
alkatrivedi Apr 5, 2024
773ba9a
Merge branch 'googleapis:main' into get-transaction-method
alkatrivedi Apr 5, 2024
aeb1129
fix: presubmit error
alkatrivedi Apr 5, 2024
943bab4
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Apr 5, 2024
9038541
fix: presubmit error
alkatrivedi Apr 5, 2024
3b00ce1
refactor: sample doc
alkatrivedi Apr 5, 2024
aaa3575
refactor: sample doc
alkatrivedi Apr 5, 2024
ee47fe4
refator: getTransaction method
alkatrivedi Apr 10, 2024
c7fedbc
fix: lint errors
alkatrivedi Apr 10, 2024
37e9bb8
fix: lint errors
alkatrivedi Apr 10, 2024
fcabb63
refactor: remove logs
alkatrivedi Apr 15, 2024
b84750a
fix: presubmit error
alkatrivedi Apr 15, 2024
b856166
fix: lint errors
alkatrivedi Apr 15, 2024
e937ba8
test: add a unit test for getTransaction
alkatrivedi Apr 15, 2024
a063abd
tests: add integration and unit test for getTransaction options prope…
alkatrivedi Apr 16, 2024
3c46110
fix: lint errors
alkatrivedi Apr 16, 2024
c45ce29
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Apr 16, 2024
415057c
refactor: naming convention for varaible in getTransaction method
alkatrivedi Apr 16, 2024
ab6112f
refactor: naming convention for varaible in getTransaction method
alkatrivedi Apr 16, 2024
d12157a
fix: lint errors
alkatrivedi Apr 16, 2024
e8c5bce
fix: lint error
alkatrivedi Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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]>;
alkatrivedi marked this conversation as resolved.
Show resolved Hide resolved
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();
alkatrivedi marked this conversation as resolved.
Show resolved Hide resolved
}
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');
alkatrivedi marked this conversation as resolved.
Show resolved Hide resolved
}
} 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 @@
});
});

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