nakagami / firebirdsql

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

Explicit transaction commit does not release database objects #75

Closed ctengiz closed 5 years ago

ctengiz commented 5 years ago

Please see below test code :

package main

import (
    "database/sql"
    "encoding/hex"
    "log"
    "os"
    "path/filepath"
    "crypto/rand"

    _ "github.com/nakagami/firebirdsql"
)

func TempFileName(prefix string) string {
    randBytes := make([]byte, 16)
    rand.Read(randBytes)
    return filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+".fdb")
}

func handleError(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func beginTx(conn *sql.DB) *sql.Tx {
    tx, err := conn.Begin()
    handleError(err)
    return tx
}

func main() {
    var tx *sql.Tx
    var err error

    temppath := TempFileName("test_basic_")
    conn, err := sql.Open("firebirdsql_createdb", "sysdba:masterkey@localhost:3050"+temppath)
    handleError(err)

    tx = beginTx(conn)
    sql := `
    create table t1 (
        id bigint generated by default as identity primary key,
        testval integer
    )
    `
    _, err = tx.Exec(sql)
    handleError(err)

    err = tx.Commit()
    handleError(err)

    // Insert values to table
    tx = beginTx(conn)
    sql = "insert into t1(testval) values (1)"
    _, err = tx.Exec(sql)
    handleError(err)

    err = tx.Commit()
    handleError(err)

    //Values are inserted, we have committed so table should not be in use

    //create another table which references to first table
    sql = `
    create table t2 (
        id bigint generated by default as identity primary key,
        t1_id bigint,
        constraint fk_t2_t1 foreign key (t1_id) references t1(id) on update cascade 
    )
    `
    tx = beginTx(conn)
    _, err = tx.Exec(sql)
    handleError(err)

    //try to commit
    err = tx.Commit()
    handleError(err)

    /* there should be no error but we get :
    2019/02/23 23:37:50 lock conflict on no wait transaction
    unsuccessful metadata update
    object TABLE "T1" is in use
    exit status 1
    */
}

When we change line 82 of transaction.go to tx.fc.wp.opCommit(tx.transHandle) code works as expected. If this is the solution then line 89 should also changed to tx.fc.wp.opRollback(tx.transHandle)

nakagami commented 5 years ago

I modified transaction treatment and push to master branch. Now, fixed this issue with master HEAD ?

ctengiz commented 5 years ago

Thank you. Seems fixed.