-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
DbUpdateConcurrencyException raised when inserting into Postgres partitioned table #30638
Comments
Duplicate of #10443 |
This seems like another case of the well-known scenario where a trigger causes EF's concurrency checks to fail. On interesting aspect here is that it happens with insertion, as opposed to update/delete; this is probably because the Npgsql provider's concurrency detection works at the PG protocol level - which reports how many rows were inserted - as opposed to the normal SQL Server/SQLite mechanism, where there's no concurrency checking on INSERT (unless there database-generated columns). It may make sense to disable the check on PG for insertions - though it would still happen with database-generated columns. Out of curiosity, is there any specific reason you're using a trigger rather than PostgreSQL's built-in declarative partitioning? Aside from being simpler, it should presumably make this error go away. |
Postgres built in partitioning isn't always a solution, it is not available in earlier versions and also due to its limitations listed here in paragraph 5.11.2.3 https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE |
@gfonkatz that's right, though as a general rule it's preferable to trigger-based partitioning when it's possible to use it. |
@gfonkatz I'm told that on SQL Server, it's possible to write the trigger in such a way that it returns the desired number of rows. I don't know enough about triggers in PostgreSQL, but something like that may be possible there as well. I'll go ahead and close this for now as a duplicate of #10443, but feel free to post back here; we can reopen if needed. |
I wish I could find a way around it by changing the trigger script. Unfortunately that's not the case. Using native partitioning is not an option for us due to its limitations. So we use the alternative recommended by PG - inheritance partitioning. That leaves us with the concurrency exception that makes no sense. |
#10443 hasn't received many votes, which is why we haven't prioritized fixing it... It's definitely something we thing should be done, but there's many more higher-priority issues on our list. |
Bug description
DbUpdateConcurrencyException is raised when inserting into partitioned table. Specifically when inheritance partitioning is used in Postgres.
Documentation is here
https://www.postgresql.org/docs/current/ddl-partitioning.html
The particular thing about inheritance partitioning in PG is that it relies on a trigger script to divert entries into partitions.
If you look at the example in the documentation you see that the trigger script returns null
Inserting a new record would cause the DB to return a result statement
INSERT 0 0
Despite saying 0 0, the record was inserted, the reason it says 0 is because trigger function returns null.
That's an expected behaviour in PG.
EF Core seems to interpret the result as a concurrency problem and gives us an error saying
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded
This is wrong, there is no problem here and an entry was actually inserted correctly.
Code
Stack traces
Include provider and version information
EF Core version: 6.0.7
Database provider: Postgres 9 and 11
Target framework: .net 6
Operating system: linux
IDE: Rider
The text was updated successfully, but these errors were encountered: