我正在使用asp.net mvc创建一个网站。我有一个看起来像这样的表
Create Table Items(
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Colname] [nvarchar](20) NOT NULL
//OTHER UNIMPORTANT COLS HERE
)
ALTER TABLE Items ADD CONSTRAINT UN_Colanme UNIQUE(Colname)
从我的网站,我经常尝试创建新项目,或从数据库中选择项目(使用实体框架)。这是它在c#中的外观。
var item = db.Items.FirstOrDefault(i => i.Colname == "foo");
if(item == null)
{
item = new Item("foo");
db.Items.Add(item);
}
//some stuff with item
db.SaveChanges();
有时,2个请求同时进入,都试图创建具有相同colname的项目。虽然唯一约束阻止数据库存储任何错误值,但尝试保存更改会引发异常,因为违反了约束。
捕获此异常是否正常处理此问题?如果不是上面的c#代码,我是否可以获得良好的性能,我创建了一个锁定表的存储过程,然后只有在允许的情况下才插入新行,然后返回该行?这是常见的吗?
答案 0 :(得分:1)
嗯,有很多方法可以做到这一点。我想说在这种情况下捕获异常是最便宜的。另一种方法是将事务隔离级别提升到更高的级别,如Serializable。
在这种情况下,我只会捕获唯一约束违规并继续。如果我们在编程术语中考虑它,我们可以考虑像double-checked locking这样的情况,因为我们检查,它不在那里,然后进入交易,看到它在那里,然后我们可以放弃我们的价值和使用那里的那个。
答案 1 :(得分:0)
这就是为什么许多开发人员使用GUID或DB分配的Ints作为唯一键。如果您的外部密钥是合法分配的并且是逻辑副本,那么请使用数据库重复约束,如您所示或考虑使用pessemistic锁。 Sql server有一个你可以使用的工具。搜索示例和博客
在网上搜索“SQL server sp_getapplock”,了解如何使用。