I am hitting an issue with Oracle and EF6 optimistic concurrency. I have an update trigger which increments a row_version field and have registered this field as a ConcurrencyToken and as being DatabaseGenerated (Computed)
The issue I am seeing is that the update query has a row count of 1 when the query actually hasn't updated the row (row_version was changed out of band)
I am putting together a reproduction now and will update once on github...
[Column("ROW_VERSION"), ConcurrencyCheck, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int? RowVersion { get; set; }
The query going over the wire is a little quirky:
declare
"ROW_VERSION" number(10,0);
"ROWID" char(18);
begin
update
"DB"."TEST"
set "NAME" = 'John Smith'
where (("ID" = 1) and ("ROW_VERSION" = 1))
returning
"ROW_VERSION",
"ROWID" into
"ROW_VERSION",
"ROWID";
open '' /* :p4 */ for select
"ROW_VERSION" as "ROW_VERSION",
"ROWID" as "ROWID"
from dual;
end;
When I try to run this query manually in SQL Developer it causes an error:
Error Message Error report - ORA-06550: line 14, column 6: PLS-00707: unsupported construct or internal error [2602] ORA-06550: line 14, column 1: PL/SQL: SQL Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.
When executed via Entity Framework no errors are reported
Dependencies:
- Oracle 12c
- EntityFramework 6.1.3
- Oracle.ManagedDataAccess.EntityFramework 12.1.2400
UPDATE I have uploaded a simple solution which reproduces the issue: https://github.com/Certegy/Concurrency/
I have found a workaround to solve this bug. When the update fails silently the 'Computed' fields are not updated to their new values... instead they are set to null.
So the solution is to manually inspect the computed fields and manually throw the DbUpdateConcurrencyException if they are null.
I hope the underlining EF bug is addressed. If someone knows where to lodge the bug report please let me know!