Last active
October 5, 2024 02:14
-
-
Save winebarrel/83ea48dbd7017cfbeb82c8b766945e91 to your computer and use it in GitHub Desktop.
contextがキャンセルされたときに*sql.Connが無効になるかの検証
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% go version | |
go version go1.23.0 darwin/arm64 | |
% grep mysql go.mod | |
github.com/go-sql-driver/mysql v1.8.1 // indirect | |
% go run main.go | |
n1: 0 | |
n1: 0 | |
[mysql] 2024/10/05 11:02:35 connection.go:49: invalid connection | |
2024/10/05 11:02:35 QueryRowContext failed (n2): driver: bad connection | |
exit status 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"database/sql" | |
"errors" | |
"fmt" | |
"log" | |
"time" | |
_ "github.com/go-sql-driver/mysql" | |
) | |
func run(ctx context.Context, db *sql.DB) error { | |
db.PingContext(ctx) | |
conn, err := db.Conn(context.TODO()) // *sql.Connの生成時にはcontextを渡さない | |
if err != nil { | |
return err | |
} | |
defer conn.Close() | |
for range 10 { | |
var n1 int | |
err = conn.QueryRowContext(ctx, "select sleep(1)").Scan(&n1) | |
if err != nil { | |
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { | |
break | |
} else { | |
return fmt.Errorf("QueryRowContext failed (n1): %w", err) | |
} | |
} | |
fmt.Println("n1:", n1) | |
} | |
var n2 int | |
err = conn.QueryRowContext(ctx, "select 2").Scan(&n2) | |
if err != nil { | |
return fmt.Errorf("QueryRowContext failed (n2): %w", err) | |
} | |
fmt.Println("n2:", n2) | |
return nil | |
} | |
func main() { | |
db, err := sql.Open("mysql", "root@tcp(localhost:13306)/mysql") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer db.Close() | |
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) | |
defer cancel() | |
err = run(ctx, db) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment