2016-07-24 69 views
0

考虑一下这个表:我如何锁定表时选择记录不返回数据

| id | objId | fieldNumber | 
|------|-------|-------------| 
| 902 | 1  | 1   | 
| 908 | 1  | 2   | 
| 1007 | 1  | 3   | 
| 1189 | 8  | 1   | 
| 1233 | 12 | 1   | 
| 1757 | 15 | 1   | 

要进入一个新的纪录,一个不存在的OBJ。可以说objId:16.对于每个obj,字段号必须增加1.看一看obj:1.正如你所看到的,它增加1.现在,如果两个或多个数据库连接尝试在相同的位置插入obj 16我会有两个obj 16与fieldNumber 1.这不会发生。我必须保证场数不一样,必须加1。

所以我的解决方案是通过objid获取所有记录。如果至少有一条记录,则在该objid的所有记录上放置一个锁,然后用下一个fieldNumber插入一条记录。

或者,当我通过objid获取所有记录时。如果没有记录,那么我将锁定整个表格,然后插入fieldNumber 1的记录。

我该如何去锁定整张桌子?让我知道如果你有更好的想法做到这一点?

回答

1

如果您可以处理异常,那么最简单的方法可能是在(objid, fieldnumber)上添加一个唯一约束。

然后你可以运行一个查询,如:

insert into t(objid, fieldnumber) 
    select @objid, coalesce(max(fieldnumber) + 1, 1) 
    from t 
    where objid = @objid; 

如果两个线程同时试图运行查询,那么唯一的约束会失败 - 而线程可以重新尝试。

您还可以使用SERIALIZABLE表提示(解释为here)。

0

似乎objIdfieldNumber一起(应该)形成该表的主键。通过这种方式进行标准化,约束将自动执行。我认为这是一个'更清洁'的解决方案。但是如果你不能放弃自动编号的PK方案,那么Gordon的解决方案是无与伦比的。

相关问题