考虑,做沿东西线的应用程序:原子“插入,如果不存在”与NHibernate
var user = session.QueryOver<User>().Where(x => x.Name==name).SingleOrDefault();
if (user == null)
{
user = new User(name);
session.Save(user);
}
业务规则规定,一个用户名必须是唯一的,这是由一个UNIQUE INDEX
支持数据库。上面的代码工作得很好,直到两个用户尝试同时注册同一个名称,都获得user == null
并尝试创建新的User
。第一个提交将会结束,第二个将失败,并从数据库中引发异常。
避免这种竞争条件的一种方法涉及将关键代码包装在lock { }
块中,但当应用程序的多个实例针对同一数据库工作时,这无关紧要。现在,如果只有我可以使用RDBS的锁定机制(在这种情况下为MS SQL)...
这是我卡住的地方。从我可以在NHibernate文档中读到的内容,我可以通过向我的QueryOver()
链添加一些提示来解决它,请求显式锁定。这将不得不是一个表锁,因为我还没有实际的行。这可能吗?
或者,我可以增加事务的隔离级别并自动获得所需的锁定吗?考虑到其他(无问题的)查询是在同一个工作单元内完成的,我怀疑这种改变会引入大量的阻塞/等待。是这样吗?
可能是我刚刚发现这个问题的一个副本:[NHibernate事务和竞争条件](http://stackoverflow.com/questions/119762/nhibernate-transaction-and-race-condition) –