考虑下表:
| id | objId | fieldNumber |
|------|-------|-------------|
| 902 | 1 | 1 |
| 908 | 1 | 2 |
| 1007 | 1 | 3 |
| 1189 | 8 | 1 |
| 1233 | 12 | 1 |
| 1757 | 15 | 1 |
我想为不存在的对象输入新记录。让我们说objId:16。对于每个obj 16,字段编号必须增加1.看看obj:1。如你所见,它增加1.现在,如果两个或多个数据库连接试图在同一时间插入obj 16时间我会有两个obj 16与fieldNumber 1.这不可能发生。我必须保证字段编号不一样,必须增加一个。
所以我的解决方案是通过objid获取所有记录。如果至少有一条记录,则通过该objid锁定所有记录,然后插入包含下一个fieldNumber的记录。
或者,当我通过objid获取所有记录时。如果没有记录,那么我将锁定整个表,然后插入一个带有fieldNumber 1的记录。
我怎样才能锁定整张桌子?如果你有更好的想法,请告诉我吗?
答案 0 :(得分:1)
如果您可以处理异常,那么最简单的方法可能是在(objid, fieldnumber)
上添加唯一约束。
然后您可以运行查询,例如:
insert into t(objid, fieldnumber)
select @objid, coalesce(max(fieldnumber) + 1, 1)
from t
where objid = @objid;
如果两个并发线程尝试运行查询,则唯一约束将失败 - 并且线程可以重新尝试。
您还可以使用SERIALIZABLE表提示(解释为here)。
答案 1 :(得分:0)
似乎objId
和fieldNumber
一起(应该)构成此表的主键。这样规范化约束将自动执行。我认为这是一个更清洁的'解。但是如果你不能放弃自动编程PK方案,那么戈登的解决方案是无与伦比的。