正如我在上面的问题中描述的那样,我正在尝试为并发问题实施悲观锁定(请随时添加到那个问题中)。但这对我不起作用。
我做了一个非常简单的测试:我运行了两个单独的站点,它们都将计数器增加了 500 倍。我同时运行它们。最后,我希望我的表中的某个列的值是 1000,你猜对了。
这是代码。这当然不是生产代码,但不管是否是测试代码,它应该仍然可以工作,对吧?
for (int i = 0; i < 500; i++)
{
var tx = this.userRepo.Session.BeginTransaction();
var user = this.userRepo.GetById(42);
user.Counter++;
userRepo.Save(user);
tx.Commit();
}
该GetById
方法使用 LockMode.Upgrade:
public T GetById(int id)
{
T obj = Session.Get<T>(id, LockMode.Upgrade);
return obj;
}
现在,使用 NHProfiler 我看到以下 SQL 语句:
SELECT Id FROM 'User' WHERE Id = 42 for update
但结果是大约530的值,因此这大约是由于并发而丢失的更新的一半。我究竟做错了什么?我在这个测试中禁用了二级缓存。我是否使用了错误的锁定模式?我应该指定隔离级别吗?还要别的吗?提前致谢。
编辑: FluentNhibernate 配置:
Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(connectionstring))
.Mappings(m => assemblyTypes.Select(t => t.Assembly).ToList().ForEach(a => m.FluentMappings.AddFromAssembly(a)))
.ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none"));