Skip to content

Foreign key constraint breaks transaction state #364

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
ipoerner opened this issue Dec 15, 2016 · 4 comments
Closed

Foreign key constraint breaks transaction state #364

ipoerner opened this issue Dec 15, 2016 · 4 comments

Comments

@ipoerner
Copy link

ipoerner commented Dec 15, 2016

A foreign key constraint that's classified as deferred (see SQLite docs here) breaks the transaction state.

Example program:

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, _ := sql.Open("sqlite3", "file::memory:")
	db.Exec(`PRAGMA foreign_keys=ON`)
	db.Exec(`CREATE TABLE "pk_table" ("id" integer not null primary key autoincrement)`)
	db.Exec(`CREATE TABLE "fk_table" ("fk" integer not null default 0 REFERENCES pk_table(id) DEFERRABLE INITIALLY DEFERRED)`)
	tx, _ := db.Begin()
	tx.Exec(`INSERT INTO "fk_table" (fk) VALUES (0)`)
	tx.Commit()
	tx, err := db.Begin()
	fmt.Println(err.Error())
}

For a more profound example with proper error checking:

fk_constraint_transaction.go.txt

According to the semantics of database/sql, a transaction must be finished after a call to tx.Commit().

However, according to SQLite documentation of deferred foreign key constraints:

Deferred foreign key constraints are not checked until the transaction tries to COMMIT. For as long as the user has an open transaction, the database is allowed to exist in a state that violates any number of deferred foreign key constraints. However, COMMIT will fail as long as foreign key constraints remain in violation.

A very similar issue was reported here: #184

@ipoerner
Copy link
Author

As you can see in the upper example, PRAGMA foreign_keys=ON is required.

@mattn
Copy link
Owner

mattn commented Apr 2, 2017

seem to be fixed by #407

@ipoerner
Copy link
Author

ipoerner commented Jun 12, 2017

@mattn Thanks for the effort. However, I keep on getting the same error even with the patch from #407:

cannot start a transaction within a transaction

@ipoerner
Copy link
Author

ipoerner commented Jun 12, 2017

This PR here: #300 addresses a similar issue, but the fix is limited to cases where the error condition is SQLITE_BUSY.

Unfortunately, the error in the case described above seems to be a very generic SQLITE_ERROR type error, which might be anything. Otherwise I would have suggested to simply extend the error check from SQLiteTx.Commit() in a way that it checks for "transaction within a transaction", too.

EDIT: Last paragraph rendered invalid.

gjrtimmer added a commit to gjrtimmer/go-sqlite3 that referenced this issue May 26, 2018
Compile Section Closes mattn#175
Compile Section Closes mattn#201
Compile Section Closes mattn#206
Compile Section Closes mattn#404
Compile Section Closes mattn#217
Compile Section Closes mattn#224
Compile Section Closes mattn#234
Compile Section Closes mattn#242
Feature table Closes mattn#255
Description Section Closes mattn#232
Golang:1.6 not supported Closes mattn#272
Golang:1.5 not supported + compilation section Closes mattn#283
usleep Implemented Closes mattn#285
FAQ Section Closes mattn#289
Compile Section closes mattn#295
FAQ Section Closes mattn#305
PR339 Closes mattn#318 mattn#321
Compilation Section Closes mattn#341
PR407 Closes mattn#364
Feature `sqlite_vtable` Closes mattn#393
Compile Section Closes mattn#416
sqlite_trace feature Closes mattn#433
Compilation Section Closes mattn#435
Compilation Section Closes mattn#443
Golang:1.6 Not Supported Closes mattn#445
Compilation Section Closes mattn#451
Compilation Section Closes mattn#467
Compilation Section Closes mattn#491
Compilation Section Closes mattn#495
Compilation Section Closes mattn#505
Compilation Section Closes mattn#557
Compilation Section Closes mattn#560
@mattn mattn closed this as completed in c9394b1 May 27, 2018
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants