ADO.Net 并发冲突 异常
数据库中有表 table1[int 工号,int 状态],其中 aaa 为主键。
内存中有与之对应的表,初始时Rows.Count=0。
当收到一个 工号 时,首先 查询数据库中有没有此工号的记录,如果没有则添加记录,如果有则修改记录。我的语句如下
DataTable t;
void form1_Load(object sender, System.EventArgs e)
{
t=dber.CreateDataTable( "select 工号,状态 from table1 where 'a '= 'b ' ")//根据SQL语句创建 DataTable。“where 'a '= 'b '”一个不可能的条件,为了使Rows.Count=0。
t.PrimaryKey=new DataColumn[]{t.Columns[ "工号 "]};
}
void 收到工号(int 工号,int 状态)
{
DataRow row=t.Rows.Find(工号);
if(row==null)
{
row=t.Rows.Add(now object[]{工号,0});//状态不会为0
row.AcceptChanges();//DataRowState.Unchanged
row[ "状态 "]=状态;//DataRowState.Modified
dber.Update(row);//★这里出错。
}
else
{
row[ "状态 "]=状态;
dber.Update(row);
}
}
------解决方案--------------------1。
虽然搞不大懂 DataSet 和 DataAdapter.Update ,但是基本明白懂 lZ 的 “策略”了,
2。
这时如果我用 dataadapter.Update()会出错,因为数据库中已经有了ID=2的行。
所以我就将 行(2,d)的状态改为Modified。
然后再dataadapter.Update(),这样 行(2,d)所运用的SQL就是更新语句了。
=========
事实上, LZ 这个“策略”确实有点 “hack”,
为什么呢? 因为你这样会导致并发冲突!!!
而且,你是自己跟自己并发了,当然数据库不理解你和自己,
数据库还是认为你和自己是两个人,
我们举 你 和 我 哈,
比如你和我,你读取了数据库的数据,而我在你更新之前也读取了数据准备修改(假设乐观锁),此时我们的数据是一样的,如下,
ID str
---------
1 a
2 b
3 c
然后我们做同样的操作,你准备更新
ID str
--------
2 d --------行状态为 Added
4 e --------行状态为 Added
而我准备更新
ID str
--------
2 Z --------行状态为 Added
4 e --------行状态为 Added
假如,我动作比你跨,我执行了更新之后,你在执行,那么你说最后的 ID =2 的 str 列数据是什么呢? 我的更新被你覆盖了啊??????
3。
问题是行的状态该了,但是dataadapter.Update()却发生“ADO.Net 并发冲突” 异常
=============
明白了没有?