mausch / FsSql

Functional wrapper around ADO.NET for F#
https://www.openhub.net/p/FsSql
Apache License 2.0
67 stars 15 forks source link

SQLite: "Library used incorrectly" #34

Open haf opened 9 years ago

haf commented 9 years ago

I'm getting an error if I call return Rollback from within a nested transactional function with Mono.Data.SQLite (or SQLite in general).

  let internal op eid = Tx.execNonQueryi "insert into ..." [ P(...) ]

  let handle  (mgr : Sql.ConnectionManager) (eid : string) (fCont : Sql.ConnectionManager -> _) =
    let execTx = tx {
      do! op eid
      let! ret = fCont
      return ret
    }

    try
      match execTx mgr with
      ... etc
    with
    | :? Mono.Data.Sqlite.SqliteException as e ->
      LogLine.create' LogLevel.Fatal "unhandled exception in read model" |> LogLine.setExn e |> LogLine.setDatas [
        "receive_tx_id", box receiveTxId
        "error_code", box e.ErrorCode
        "stack_trace", box e.StackTrace
      ] |> Logger.log logger
      reraise ()

The 'Misuse' status code comes from the exception SqliteException.

F 2015-04-29T15:40:12.8422210+00:00: unhandled exception in read model
  error_code => Misuse
  receive_tx_id => "xxxxxxx"
  stack_trace => "  at Mono.Data.Sqlite.SqliteTransaction.IsValid (Boolean throwError) [0x00094] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.1/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteTransaction.cs:168
  at Mono.Data.Sqlite.SqliteTransaction.Rollback () [0x00000] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.1/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteTransaction.cs:127
  at Tx+onFailed@131-1[System.Exception].Invoke (IDbTransaction tran, System.Exception _arg3) [0x00000] in <filename unknown>:0
  at Microsoft.FSharp.Core.FSharpFunc`2[System.Data.IDbTransaction,System.Exception].InvokeFast[Unit] (Microsoft.FSharp.Core.FSharpFunc`2 func, IDbTransaction arg1, System.Exception arg2) [0x00000] in <filename unknown>:0
  at Tx.subscribe@113[Unit,Unit] (Microsoft.FSharp.Core.FSharpFunc`2 f, IDbTransaction tx, Microsoft.FSharp.Core.FSharpFunc`2 onCommit, Microsoft.FSharp.Core.FSharpFunc`2 onRollback, Microsoft.FSharp.Core.FSharpFunc`2 onFailed) [0x00000] in <filename unknown>:0
  at Tx+transactional@127-1[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit].Invoke (IDbConnection conn) [0x00000] in <filename unknown>:0
  at FsSqlPrelude.withResource[IDbConnection,TxResult`2] (Microsoft.FSharp.Core.FSharpFunc`2 create, Microsoft.FSharp.Core.FSharpFunc`2 dispose, Microsoft.FSharp.Core.FSharpFunc`2 action) [0x00000] in <filename unknown>:0
  at Tx+Run@134[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit].Invoke (ConnectionManager cmgr) [0x00000] in <filename unknown>:0
  at Mod.handle[Unit,Unit] (ConnectionManager mgr, System.String eid, Microsoft.FSharp.Core.FSharpFunc`2 fCont) [0x00000] in <filename unknown>:0 " cont...
Mono.Data.Sqlite.SqliteException: Library used incorrectly
No transaction is active on this connection
  at Mono.Data.Sqlite.SqliteTransaction.IsValid (Boolean throwError) [0x00094] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.1/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteTransaction.cs:168
  at Mono.Data.Sqlite.SqliteTransaction.Rollback () [0x00000] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.1/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteTransaction.cs:127
  at Tx+onFailed@131-1[System.Exception].Invoke (IDbTransaction tran, System.Exception _arg3) [0x00000] in <filename unknown>:0
  at Microsoft.FSharp.Core.FSharpFunc`2[System.Data.IDbTransaction,System.Exception].InvokeFast[Unit] (Microsoft.FSharp.Core.FSharpFunc`2 func, IDbTransaction arg1, System.Exception arg2) [0x00000] in <filename unknown>:0
  at Tx.subscribe@113[Unit,Unit] (Microsoft.FSharp.Core.FSharpFunc`2 f, IDbTransaction tx, Microsoft.FSharp.Core.FSharpFunc`2 onCommit, Microsoft.FSharp.Core.FSharpFunc`2 onRollback, Microsoft.FSharp.Core.FSharpFunc`2 onFailed) [0x00000] in <filename unknown>:0
  at Tx+transactional@127-1[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit].Invoke (IDbConnection conn) [0x00000] in <filename unknown>:0
  at FsSqlPrelude.withResource[IDbConnection,TxResult`2] (Microsoft.FSharp.Core.FSharpFunc`2 create, Microsoft.FSharp.Core.FSharpFunc`2 dispose, Microsoft.FSharp.Core.FSharpFunc`2 action) [0x00000] in <filename unknown>:0
  at Tx+Run@134[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit].Invoke (ConnectionManager cmgr) [0x00000] in <filename unknown>:0
  at Mod.handle[Unit,Unit] (ConnectionManager mgr, System.String eid, Microsoft.FSharp.Core.FSharpFunc`2 fCont) [0x00000] in <filename unknown>:0

This issue doesn't seem to have anything to do with the other two issues I commented on earlier today.

This issue should trigger reliably by throwing an exception from fCont.

mausch commented 9 years ago

As usual, the first step is to reproduce it in a test case that we can add to the FsSql codebase.