我正在调查Devart.Data.Linq.ChangeConflictException: Row not found or changed
的间歇性事件。
我一直在阅读关于concurrency conflicts的Devart文章,作为一个起点,我试图重现并发冲突。使用包含的基于MS的LINQ类,这很容易做到(使用下面的代码结构成功)。然而,即使遵循他们在文章中的示例我也不能产生异常。我试过了
这是我正在使用的测试代码:
public static void MySqlTest()
{
using (MySqlDataContext db = new MySqlDataContext())
{
Customer customer = db.Customers.First(c => c.Username.Equals("ian2"));
MySqlAdoChange(db.Connection);
//MySqlLinqConnectChange();
customer.Address1 = "Original change" + DateTime.UtcNow.Ticks;
db.SubmitChanges();
}
}
public static void MySqlAdoChange(DbConnection connection)
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "UPDATE customers SET Address1 = 'Conflicting change" + DateTime.UtcNow.Ticks + "' WHERE Username = 'ian2'";
command.ExecuteNonQuery();
}
public static void MySqlLinqConnectChange()
{
using (MySqlDataContext db = new MySqlDataContext())
{
Customer customer = db.Customers.First(c => c.Username.Equals("ian2"));
customer.Address1 = "Conflicting change" + DateTime.UtcNow.Ticks;
db.SubmitChanges();
}
}
更奇怪的是,保存到数据库的值在两者之间交替显示!
我必须在最后添加DateTime滴答以确保唯一性,否则它会优化我的更新,并且只更新为当前未激活的值。
任何人都可以解释这种行为吗?为什么我不能生成ChangeConflictException?
答案 0 :(得分:1)
首先请注意,在您的示例代码中,您更新了Phone
函数中的MySqlTest
字段,但更新了Address1
函数中的MySqlAdoChange
字段,因此不存在任何冲突。< / p>
但是,即使你纠正了这一点,你也不会有更新冲突。如果您在Customer
属性中查看Phone
类源代码,您(很可能)会看到它使用UpdateCheck = UpdateCheck.Never
的Column属性进行修饰(这是默认值:请参阅此处{ {3}})。因此,默认情况下,LinqConnect不会检查您的字段的更新冲突,除非您通过使用UpdateCheck = UpdateCheck.Always
或UpdateCheck.WhenChanged
进行装饰来告诉它要检查哪些字段。当然,您不应该直接修改源代码,而是在模型设计器中更改该属性。