nakagami / firebirdsql

Firebird RDBMS sql driver for Go (golang)
MIT License
224 stars 60 forks source link

long time query with context dont work #115

Closed spouk closed 1 year ago

spouk commented 3 years ago

example mysql and firebird, mysql correcty timeout context situation, firebird driver freezy .....

package main
import (
    "context"
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    _ "github.com/nakagami/firebirdsql"
    "time"
)
func main() {
    var (
        nodeFirebird = "sysdba:sysdba@localhost:3050/employee"
        //nodeMysql = "spouk:spouk@/tester"
    )

    checkFirebirdTimeout(nodeFirebird, 1)
    //checkmysqlLongQueryContext(nodeMysql, 7, 5)
}

//
//example firebird function long time query
func checkFirebirdTimeout(node string, timeout int) {
    conn, err := sql.Open("firebirdsql", node)
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }
    defer conn.Close()
    //long time query ~rime query = 10sec
    var reqSQLLong = `
                    execute block
                    as
                declare c integer = 0;
                begin
        while (c < 90000000 ) do
            begin
                c = c + 1;
            end
        end
                        `
    //make new context
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(timeout))
    defer cancel()

    //делаю выборку из базы данных
    var n int
    //qr, err := conn.QueryContext(ctx, "select  first 1 MON$SERVER_PID  from MON$ATTACHMENTS;")
    qr := conn.QueryRowContext(ctx, reqSQLLong)
    err = qr.Scan(&n)
    if ctx.Err() == context.DeadlineExceeded {
        fmt.Printf("[время сессии истекло]\n")
        return
    }
    //ошибка запроса в рамках контекста = 2
    if err != nil {
        fmt.Printf("[error] %v\n", err)
        return
    }
    fmt.Printf("[all ok]\n")

}
//mysql long query example with context
func checkmysqlLongQueryContext(node string,  sleepTime, timeout int) {
    db, err := sql.Open("mysql", node)
    if err != nil {
        fmt.Printf("%v\n",err)
        return
    }
    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(timeout))
    defer cancel()
    res := db.QueryRowContext(ctx, fmt.Sprintf("select sleep(%d)", sleepTime))
    id := -1

    err = res.Scan(&id)
    if err != nil {
        fmt.Printf("[error] ошибка при выборке  %v\n", err)
    }
    //timeout context
    if ctx.Err() == context.DeadlineExceeded {
        fmt.Printf("[error] время контекста истекло\n")
    }
    fmt.Printf("[all ok] result %v\n", id)
}
nakagami commented 1 year ago

@spouk Merged pull request #146. Is this not resolving the issue?