Skip to content

Commit 9a67221

Browse files
committed
Fix request tags behavior
1 parent 0ec9c18 commit 9a67221

File tree

4 files changed

+55
-19
lines changed

4 files changed

+55
-19
lines changed

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,13 @@ Note that transaction-level priority takes precedence over command-level priorit
272272

273273
In a read-write transaction, you can add a tag following `BEGIN RW TAG <tag>`.
274274
spanner-cli adds the tag set in `BEGIN RW TAG` as a transaction tag.
275-
The tag will also be used as request tags within the transaction.
275+
The tag will also be used as the prefix of request tags within the transaction.
276+
277+
spanner-cli generates request tags in the following format.
278+
279+
`<request tag>` ::= `<transaction tag>_<sequence number>_<SQL Text>`
280+
281+
Because the length of a request_tag is [limited to 50 characters](https://github.com/googleapis/googleapis/blob/150b4079b6441ea8b3d7f9a71d0be7bbacbb4e3a/google/spanner/v1/spanner.proto#L466-L476), request tags, especially SQL Text embedded at the end of a request tag, may be truncated.
276282

277283
```
278284
# Read-write transaction
@@ -281,27 +287,28 @@ The tag will also be used as request tags within the transaction.
281287
| BEGIN RW TAG tx1; |
282288
| |
283289
| SELECT val |
284-
| FROM tab1 +-----request_tag = tx1
290+
| FROM tab1 +-----request_tag = tx1_1_SELECT val...
285291
| WHERE id = 1; |
286292
| |
287293
| UPDATE tab1 |
288-
| SET val = 10 +-----request_tag = tx1
294+
| SET val = 10 +-----request_tag = tx1_2_UPDATE tab1...
289295
| WHERE id = 1; |
290296
| |
291297
| COMMIT; |
292298
+--------------------+
293299
```
294300

295301
In a read-only transaction, you can add a tag following `BEGIN RO TAG <tag>`.
296-
Since read-only transaction doesn't support transaction tag, spanner-cli adds the tag set in `BEGIN RO TAG` as request tags.
302+
Since read-only transaction doesn't support transaction tag, spanner-cli adds the tag set in `BEGIN RO TAG` as the prefix of request tags.
303+
297304
```
298305
# Read-only transaction
299306
# transaction_tag = N/A
300307
+--------------------+
301308
| BEGIN RO TAG tx2; |
302309
| |
303310
| SELECT SUM(val) |
304-
| FROM tab1 +-----request_tag = tx2
311+
| FROM tab1 +-----request_tag = tx2_1_SELECT SUM(val)...
305312
| WHERE id = 1; |
306313
| |
307314
| CLOSE; |

integration_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ func TestReadWriteTransaction(t *testing.T) {
285285
IsMutation: true,
286286
})
287287

288+
if session.tc.statementCounter != 2 {
289+
t.Errorf("Check the current statement number, Expect 2, Actual %d", session.tc.statementCounter)
290+
}
291+
288292
// commit
289293
stmt, err = BuildStatement("COMMIT")
290294
if err != nil {
@@ -368,6 +372,10 @@ func TestReadWriteTransaction(t *testing.T) {
368372
IsMutation: true,
369373
})
370374

375+
if session.tc.statementCounter != 2 {
376+
t.Errorf("Check the current statement number, Expect 2, Actual %d", session.tc.statementCounter)
377+
}
378+
371379
// rollback
372380
stmt, err = BuildStatement("ROLLBACK")
373381
if err != nil {
@@ -485,6 +493,10 @@ func TestReadOnlyTransaction(t *testing.T) {
485493
IsMutation: false,
486494
})
487495

496+
if session.tc.statementCounter != 2 {
497+
t.Errorf("Check the current statement number, Expect 2, Actual %d", session.tc.statementCounter)
498+
}
499+
488500
// close
489501
stmt, err = BuildStatement("CLOSE")
490502
if err != nil {
@@ -556,6 +568,10 @@ func TestReadOnlyTransaction(t *testing.T) {
556568
IsMutation: false,
557569
})
558570

571+
if session.tc.statementCounter != 2 {
572+
t.Errorf("Check the current statement number, Expect 2, Actual %d", session.tc.statementCounter)
573+
}
574+
559575
// close
560576
stmt, err = BuildStatement("CLOSE")
561577
if err != nil {

session.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ type Session struct {
5858
}
5959

6060
type transactionContext struct {
61-
tag string
62-
priority pb.RequestOptions_Priority
63-
sendHeartbeat bool // Becomes true only after a user-driven query is executed on the transaction.
64-
rwTxn *spanner.ReadWriteStmtBasedTransaction
65-
roTxn *spanner.ReadOnlyTransaction
61+
statementCounter int64 // Count current statement number in a transaction
62+
tag string
63+
priority pb.RequestOptions_Priority
64+
sendHeartbeat bool // Becomes true only after a user-driven query is executed on the transaction.
65+
rwTxn *spanner.ReadWriteStmtBasedTransaction
66+
roTxn *spanner.ReadOnlyTransaction
6667
}
6768

6869
func NewSession(projectId string, instanceId string, databaseId string, priority pb.RequestOptions_Priority, opts ...option.ClientOption) (*Session, error) {
@@ -129,9 +130,10 @@ func (s *Session) BeginReadWriteTransaction(ctx context.Context, priority pb.Req
129130
return err
130131
}
131132
s.tc = &transactionContext{
132-
tag: tag,
133-
priority: priority,
134-
rwTxn: txn,
133+
statementCounter: 1, // Reset counter
134+
tag: tag,
135+
priority: priority,
136+
rwTxn: txn,
135137
}
136138
return nil
137139
}
@@ -195,9 +197,10 @@ func (s *Session) BeginReadOnlyTransaction(ctx context.Context, typ timestampBou
195197
}
196198

197199
s.tc = &transactionContext{
198-
tag: tag,
199-
priority: priority,
200-
roTxn: txn,
200+
statementCounter: 1, // Reset counter
201+
tag: tag,
202+
priority: priority,
203+
roTxn: txn,
201204
}
202205

203206
return txn.Timestamp()
@@ -255,13 +258,13 @@ func (s *Session) RunAnalyzeQuery(ctx context.Context, stmt spanner.Statement) (
255258

256259
func (s *Session) runQueryWithOptions(ctx context.Context, stmt spanner.Statement, opts spanner.QueryOptions) (*spanner.RowIterator, *spanner.ReadOnlyTransaction) {
257260
if s.InReadWriteTransaction() {
258-
opts.RequestTag = s.tc.tag
261+
opts.RequestTag = generateRequestTag(s.tc, stmt)
259262
iter := s.tc.rwTxn.QueryWithOptions(ctx, stmt, opts)
260263
s.tc.sendHeartbeat = true
261264
return iter, nil
262265
}
263266
if s.InReadOnlyTransaction() {
264-
opts.RequestTag = s.tc.tag
267+
opts.RequestTag = generateRequestTag(s.tc, stmt)
265268
return s.tc.roTxn.QueryWithOptions(ctx, stmt, opts), s.tc.roTxn
266269
}
267270

@@ -278,7 +281,7 @@ func (s *Session) RunUpdate(ctx context.Context, stmt spanner.Statement) (int64,
278281

279282
opts := spanner.QueryOptions{
280283
Priority: s.currentPriority(),
281-
RequestTag: s.tc.tag,
284+
RequestTag: generateRequestTag(s.tc, stmt),
282285
}
283286
rowCount, err := s.tc.rwTxn.UpdateWithOptions(ctx, stmt, opts)
284287
s.tc.sendHeartbeat = true
@@ -374,3 +377,7 @@ func heartbeat(txn *spanner.ReadWriteStmtBasedTransaction, priority pb.RequestOp
374377
_, err := iter.Next()
375378
return err
376379
}
380+
381+
func generateRequestTag(tc *transactionContext, stmt spanner.Statement) string {
382+
return tc.tag + "_" + fmt.Sprintf("%d", tc.statementCounter) + "_" + stmt.SQL
383+
}

statement.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ func (s *SelectStatement) Execute(ctx context.Context, session *Session) (*Resul
225225
}
226226
return nil, err
227227
}
228+
229+
if session.InReadWriteTransaction() || session.InReadOnlyTransaction() {
230+
session.tc.statementCounter++
231+
}
232+
228233
result := &Result{
229234
ColumnNames: columnNames,
230235
Rows: rows,
@@ -749,6 +754,7 @@ func (s *DmlStatement) Execute(ctx context.Context, session *Session) (*Result,
749754
rollback.Execute(ctx, session)
750755
return nil, fmt.Errorf("transaction was aborted: %v", err)
751756
}
757+
session.tc.statementCounter++
752758
} else {
753759
// Start implicit transaction.
754760
begin := BeginRwStatement{}

0 commit comments

Comments
 (0)