New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQLite Provider using Microsoft.Data.Sqlite library does not perform updates transactionally #816
Comments
That is weird. What if you do new transaction and wrap the datacontext inside it, something like this: open System.Transactions
[<EntryPoint>]
let main _ =
let scope = new Transactions.TransactionScope(Transactions.TransactionScopeAsyncFlowOption.Enabled)
let ctx = sqLite.GetDataContext()
let parent = ctx.Main.Parent.Create()
parent.Name <- Some "Hello"
ctx.Main.Child.``Create(ParentId)``(100) |> ignore
ctx.SubmitUpdates()
scope.Complete()
0 |
I tried that but the parent row still gets committed to the database. |
I think it might be a problem with
|
Definitely it's issue in Microsoft.Data.Sql, but I'm not sure if they fix it or just close it "as designed": I'd expect the problem is that they don't support System.Transactions as every other .NET database driver, but they have some custom way of doing their transactions. But you never know, it could maybe easy for them to add a wrapper to their library to implement proper transactions with their current implementation. The benefits of using System.Transactions is clear: what if you want a transaction over multiple data sources, without them you'd have to write lot of non-happy-path code that is hard to test. |
@Thorium based on what you say, do you think it would be a lot of work to adapt SQLProvider to use Microsof.Data.Sql BeginTransaction and EndTransaction methods? From a quick look at the source, it seems relatively simple to add a condition for the transaction scope in the ProcessUpdatesAsync and ProcessUpdates methods of the SQLiteProvider class. I can also do it and send a pull request. What do you think? |
Sure, the main concern is will that break System.Data.SQLite. |
Well, I was thinking on a condition that selects which transaction scope to use based on the selected SQLite library. There are already similar match expressions in the SQLite provider implementation (see example below). Using something similar it should be possible to support Microsoft.Data.Sqlite transactions without breaking System.Data.SQLite.
|
Describe the bug
Updates from SQLProvider should be transactional. In the example below, the row in the Parent table is created even though the creation of the Child row fails because of the foreign key constraint (assuming no row with ID=100 exists in the Parent table).
Notice that SQLProvider behaves correctly when using
System.Data.SQLite
instead ofMicrosoft.Data.Sqlite
as library.To Reproduce
Database definitions
Program.fs
Project file
Expected behavior
Assuming a row with ID=100 does not exist in the Parent table, the transaction should rollback and no new rows should be created in the Database.
System Info
The text was updated successfully, but these errors were encountered: