Skip to content

Commit 2a9dcfe

Browse files
committed
added transactions example for table client
1 parent c16d20b commit 2a9dcfe

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Using transactions over YDB query service client
2+
3+
## Runing code snippet
4+
```bash
5+
go run -ydb="grpcs://endpoint/?database=database"
6+
```
7+
8+

examples/transaction/table/main.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"os"
8+
"strings"
9+
10+
ydb "github.com/ydb-platform/ydb-go-sdk/v3"
11+
"github.com/ydb-platform/ydb-go-sdk/v3/table"
12+
"github.com/ydb-platform/ydb-go-sdk/v3/table/types"
13+
)
14+
15+
var dsn string
16+
17+
func init() { //nolint:gochecknoinits
18+
required := []string{"ydb"}
19+
flagSet := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
20+
flagSet.Usage = func() {
21+
out := flagSet.Output()
22+
_, _ = fmt.Fprintf(out, "Usage:\n%s [options]\n", os.Args[0])
23+
_, _ = fmt.Fprintf(out, "\nOptions:\n")
24+
flagSet.PrintDefaults()
25+
}
26+
flagSet.StringVar(&dsn,
27+
"ydb", "",
28+
"YDB connection string",
29+
)
30+
if err := flagSet.Parse(os.Args[1:]); err != nil {
31+
flagSet.Usage()
32+
os.Exit(1)
33+
}
34+
flagSet.Visit(func(f *flag.Flag) {
35+
for i, arg := range required {
36+
if arg == f.Name {
37+
required = append(required[:i], required[i+1:]...)
38+
}
39+
}
40+
})
41+
if len(required) > 0 {
42+
fmt.Printf("\nSome required options not defined: %v\n\n", required)
43+
flagSet.Usage()
44+
os.Exit(1)
45+
}
46+
}
47+
48+
func main() {
49+
ctx, cancel := context.WithCancel(context.Background())
50+
defer cancel()
51+
db, err := ydb.Open(ctx, dsn)
52+
if err != nil {
53+
panic(err)
54+
}
55+
defer db.Close(ctx)
56+
57+
if words, err := txWithRetries(ctx, db); err != nil {
58+
panic(err)
59+
} else {
60+
fmt.Printf("SUCCESS: %q\n", strings.Join(words, " "))
61+
}
62+
}
63+
64+
func txWithRetries(ctx context.Context, db *ydb.Driver) (words []string, _ error) {
65+
err := db.Table().DoTx(ctx, func(ctx context.Context, tx table.TransactionActor) error {
66+
words = words[:0] // empty for new retry attempt
67+
68+
result, err := tx.Execute(ctx, "SELECT 'execute';", nil)
69+
if err != nil {
70+
return err
71+
}
72+
73+
if err := result.NextResultSetErr(ctx); err != nil {
74+
return err
75+
}
76+
77+
if !result.NextRow() {
78+
return fmt.Errorf("no row")
79+
}
80+
81+
var s string
82+
if err := result.Scan(&s); err != nil {
83+
return err
84+
}
85+
86+
words = append(words, s)
87+
88+
if err = result.Err(); err != nil {
89+
return err
90+
}
91+
92+
_ = result.Close()
93+
94+
result, err = tx.Execute(ctx, `
95+
DECLARE $word1 AS Text;
96+
DECLARE $word2 AS Text;
97+
DECLARE $word3 AS Text;
98+
99+
SELECT w, ord FROM (
100+
SELECT $word1 AS w, 1 AS ord
101+
UNION
102+
SELECT $word2 AS w, 2 AS ord
103+
UNION
104+
SELECT 'with'u AS w, 3 AS ord
105+
UNION
106+
SELECT $word3 AS w, 4 AS ord
107+
UNION
108+
SELECT 'using'u AS w, 5 AS ord
109+
UNION
110+
SELECT 'db.Table().DoTx()'u AS w, 6 AS ord
111+
)
112+
ORDER BY ord;
113+
`,
114+
table.NewQueryParameters(
115+
table.ValueParam("$word1", types.TextValue("in")),
116+
table.ValueParam("$word2", types.TextValue("transaction")),
117+
table.ValueParam("$word3", types.TextValue("retries")),
118+
),
119+
)
120+
if err != nil {
121+
return err
122+
}
123+
124+
defer result.Close()
125+
126+
if err := result.NextResultSetErr(ctx); err != nil {
127+
return err
128+
}
129+
130+
for result.NextRow() {
131+
var (
132+
word string
133+
ord int
134+
)
135+
err = result.Scan(&word, &ord)
136+
if err != nil {
137+
return err
138+
}
139+
words = append(words, word)
140+
}
141+
142+
return result.Err()
143+
})
144+
if err != nil {
145+
return nil, err
146+
}
147+
148+
return words, nil
149+
}

0 commit comments

Comments
 (0)