Skip to content

Commit

Permalink
Fix transactions not being rolled back when the individual statements…
Browse files Browse the repository at this point in the history
… succeed, but the committing the transaction fails.
  • Loading branch information
MrMage committed Aug 22, 2016
1 parent abab39b commit d5ede25
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
2 changes: 1 addition & 1 deletion SQLite/Core/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,11 @@ public final class Connection {
try self.run(begin)
do {
try block()
try self.run(commit)
} catch {
try self.run(rollback)
throw error
}
try self.run(commit)
}
}

Expand Down
27 changes: 27 additions & 0 deletions SQLiteTests/ConnectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,33 @@ class ConnectionTests : SQLiteTestCase {
AssertSQL("ROLLBACK TRANSACTION", 0)
}

func test_transaction_rollsBackTransactionsIfCommitsFail() {
// This test case needs to emulate an environment where the individual statements succeed, but committing the
// transactuin fails. Using deferred foreign keys is one option to achieve this.
try! db.execute("PRAGMA foreign_keys = ON;")
try! db.execute("PRAGMA defer_foreign_keys = ON;")
let stmt = try! db.prepare("INSERT INTO users (email, manager_id) VALUES (?, ?)", "alice@example.com", 100)

do {
try db.transaction {
try stmt.run()
}
} catch {
}

AssertSQL("BEGIN DEFERRED TRANSACTION")
AssertSQL("INSERT INTO users (email, manager_id) VALUES ('alice@example.com', 100)")
AssertSQL("COMMIT TRANSACTION")
AssertSQL("ROLLBACK TRANSACTION")

// Run another transaction to ensure that a subsequent transaction does not fail with an "cannot start a
// transaction within a transaction" error.
let stmt2 = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com")
try! db.transaction {
try stmt2.run()
}
}

func test_transaction_beginsAndRollsTransactionsBack() {
let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com")

Expand Down

0 comments on commit d5ede25

Please sign in to comment.