2011-06-01 83 views
1

我的C#程序中执行以下操作(伪代码):数据库行锁定

START TRANSACTION READ COMMITTED 
Select isOriginal, * from myTable where tnr = x; 
//Record found? 
Yes: 
    //isOriginal? 
    Yes: 
    update myTable set is_active = 0 where tnr = x; 
    No: 
    delete from myTable where tnr = x; 
    //Do some simple logic on the values 
    Insert into myTable (newvalues) 
No: 
    return record_not_found; 
END TRANSACTION 

然而,当我开始我的程序的两个实例,并都同时插入两个记录作为编辑同一条记录他们都在选择查询中找到记录。

应该发生的事情是第一个事务找到记录并插入一个新行,而第二个事务返回一条未找到的记录。

我该如何解决这个问题?把我的交易序列化?检查更新/删除的返回值?最好的方法是什么?

编辑

应该基于Sybase,甲骨文& SQL Server的工作。

+0

您使用什么数据库只是做? – 2011-06-01 14:33:45

+0

你肯定他们正在同时编辑?请记住,数据库时间非常非常非常非常精确,因此您不会碰到记录锁。他们还会在尝试再次进行交易之前让其中一个进程等待一段时间。 – Limey 2011-06-01 14:35:30

+0

就像一个建议和良好的编程practive,从来没有'SELECT *'。列出你需要的所有列名,即使它是整个表。你永远不知道这个表何时会被另一个开发者修改。 – JonH 2011-06-01 14:45:35

回答

0

如果您使用的是MS SQL您需要查看NOLOCKROWLOCK NOLOCK告诉SQL Server忽略任何类型的锁并直接从实际表中读取。亲是它有很好的表现,这样你就可以绕过一个锁定的系统。另一方面,ROWLOCK要求SQL Server使用行级锁。性能确实与ROWLOCK阻碍,所以你需要确定是否需要对UPDATES/DELETES

锁定在你的情况SELECT isOriginal, * FROM myTable WITH (NOLOCK) WHERE tnr=x

然后UPDATE myTable WITH (ROWLOCK) SET is_active=0 WHERE tnr=x

0

不知道什么数据库使用的是你可以设置一个锁场在分贝。

其中每个并发线程都有一个PID或线程ID或至少一种独特的时间戳 一个

update myTable set lock = <pid> where pid = null limit 1; 

select isOriginal, * from myTable where lock = <pid>