1

我有一个 ASP.NET 应用程序,它使用 NHibernate 在用户操作时以事务方式更新一些表。涉及到一个日期范围,其中只能对表格“预订”进行一个条目,以便指定排他日期。

我的问题是如何防止竞争条件,即两个用户操作几乎同时发生并导致多个条目进入“预订”>1 日期。我不能在调用 .Commit() 之前检查,因为我认为这仍然会导致竞争条件?

我所能看到的只是在提交后进行检查并手动回滚更改,但这让我的嘴巴感觉很糟糕!:)

booking_ref (INT) PRIMARY_KEY AUTOINCREMENT

预订开始(日期时间)

预订结束(日期时间)

4

3 回答 3

5
  • 使您的事务 SERIALIZABLE ( session.BeginTransaction(IsolationLevel.Serializable) 的隔离级别,并检查并插入同一个事务。通常不应该将隔离级别设置为可序列化,只是在这种情况下。

或者

  • 在检查并最终插入之前锁定表。您可以通过 nhibernate 触发 SQL 查询来做到这一点:

    session.CreateSQLQuery("SELECT null as dummy FROM Booking WITH (tablockx, holdlock)").AddScalar("dummy", NHibernateUtil.Int32); 这将在该事务期间仅锁定该表以进行选择/插入。

希望它有所帮助

于 2008-09-23T10:38:15.863 回答
0

上述解决方案可以作为一个选项使用。如果我在事务级别可序列化时使用“Parallel.For”发送了 100 个请求,是的,没有重复的请求 ID,但 25 个事务失败。我的客户不能接受。因此,我们通过仅存储请求 ID 并在其他表上添加唯一索引作为临时索引来解决问题。

于 2017-02-20T08:10:30.490 回答
-1

您的数据库应该管理您的数据完整性。

您可以使您的“日期”列独一无二。因此,如果 2 个线程尝试获取相同的日期。一个将引发唯一的密钥违规,另一个将成功。

于 2012-12-12T16:19:03.407 回答