-
Notifications
You must be signed in to change notification settings - Fork 125
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
SNOW-1771421: Rollback transaction doesn't work if transaction is opened with a context #1233
Comments
thank you for raising this and for the details, i'll take a look int the coming days. appreciate sharing the reproduction approach! |
i tried to figure out what's in package main
import (
"context"
"database/sql"
"fmt"
"log"
"strconv"
sf "github.com/snowflakedb/gosnowflake"
)
func runningTxsCount(conn *sql.Conn, ctx context.Context) int {
rows, err := conn.QueryContext(ctx, "SHOW /* gosnowflake 1233 */ TRANSACTIONS;")
if err != nil {
log.Fatal("error in runningTxsCount: ", err)
}
defer rows.Close()
counter := 0
for rows.Next() {
counter++
}
return counter
}
func main() {
cfg, err := sf.GetConfigFromEnv([]*sf.ConfigParam{
{Name: "Account", EnvName: "SNOWFLAKE_TEST_ACCOUNT", FailOnMissing: true},
{Name: "User", EnvName: "SNOWFLAKE_TEST_USER", FailOnMissing: true},
{Name: "Password", EnvName: "SNOWFLAKE_TEST_PASSWORD", FailOnMissing: true},
})
if err != nil {
log.Fatalf("failed to create Config, err: %v", err)
}
//cfg.Tracing = "TRACE"
dsn, err := sf.DSN(cfg)
if err != nil {
log.Fatalf("failed to create DSN from Config: %v, err: %v", cfg, err)
}
db, err := sql.Open("snowflake", dsn)
if err != nil {
log.Fatalf("failed to connect. %v, err: %v", dsn, err)
}
defer db.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
conn, err := db.Conn(ctx)
if err != nil {
log.Fatalf("Failed to acquire connection. err: %v", err)
}
defer conn.Close()
txIDCh := make(chan int, 1)
cancelledCh := make(chan struct{}, 1)
doneCh := make(chan struct{}, 1)
go func() {
tx, err := conn.BeginTx(ctx, nil) // Using sf.Begin() is fine
if err != nil {
log.Fatal(err)
}
defer func() {
err := tx.Rollback()
if err != nil {
fmt.Printf("Rollback failed: %v\n", err)
}
fmt.Printf("transaction is rollbacked\n")
doneCh <- struct{}{}
}()
var txID int
if err := tx.QueryRowContext(ctx, "SELECT /* gosnowflake 1233 */ CURRENT_TRANSACTION();").Scan(&txID); err != nil {
log.Fatal(err)
}
log.Print("--> txID in goroutine: " + strconv.Itoa(txID))
txIDCh <- txID
<-cancelledCh
}()
txID := <-txIDCh
log.Print("--> txID outside goroutine: " + strconv.Itoa(txID))
cancel()
cancelledCh <- struct{}{}
<-doneCh
if runningTxsCount(conn, ctx) != 0 { // Use "SHOW TRANSACTIONS;"
log.Print("transaction is still running")
_, err := conn.ExecContext(ctx, "SELECT /* gosnowflake 1233 */ SYSTEM$ABORT_TRANSACTION(?);", txID)
if err != nil {
log.Fatal(err)
}
}
} using the latest gosnowflake of 1.12.0
in Query History in Snowflake, only 2 statements are seen, in reverse order:
It is entirely possible of course, that I'm doing something wrong, so would it be please possible for you to
|
You are right, the context is cancelled. That's why The problem I met here is that, if the context is cancelled, the transaction is still in running status in Snowflake. Locks hold by this transaction won't be released, and other queries requiring this lock will be blocked. What I expect is that, if the context used by
|
thank you for the additional info ! we'll take a look at this issue. |
Hello! I took a look and my findings are:
We will create an issue for one of our backend teams to take a look at this topic. |
Thanks for the update. My guess is that the driver is reusing the already-cancelled context to send the abort request, and thus the request is not sent. |
Actually the abort request is sent correctly (source), but it doesn't rollback transaction on the backend side. |
Giving it another thought, we agreed that it's a bit more complicated. We see a case in which cancelling context should rollback transaction, but:
|
Please answer these questions before submitting your issue.
In order to accurately debug the issue this information is required. Thanks!
What version of GO driver are you using?
v1.9.0
What operating system and processor architecture are you using?
MacOS 15.0.1 (24A348), M2 Max
What version of GO are you using?
go version go1.23.2 darwin/arm64
4.Server version:* E.g. 1.90.1
8.40.1
What did you expect to see?
The transaction should be aborted.
The text was updated successfully, but these errors were encountered: