0

我正在开发 MVC Web 应用程序。

这意味着我正在创建视图、模型、视图模型。我使用 linq-to-sql 作为数据库提供程序,我已经实现了自定义工作单元SQL模式,以及看起来完美(在我的实现中)并且与直接代码完全分离的数据源、存储库和服务模式。实际上,从任何为单元测试而设计的数据库中,我都可以使用内存数据源测试我的应用程序,而不会影响数据库。

最终我遇到了一个问题:我没有针对跨线程(或跨进程,因为据我所知,IIS可以使用单个 Web 应用程序创建多个应用程序域)操作的保护。

例如,我有一个包含一些记录的表。并且每隔一段时间就会发生一个 Web 请求(在控制器内部,然后是服务,然后是存储库)在假设TicketId列的最大值上选择 SQL 表的行,然后在该表中插入另一行(that column value + 1)

如果两个或多个线程或进程执行相同的操作,重复的值可能会出现在数据库中。前段时间,当我的 web 应用程序变小时,我使用了直接 SQL 代码和简单UPDLOCKSELECT语句,其中using块内部锁定了我正在修改的记录(或其他任何内容),以防止所有其他数据库客户端等到我完成。TransactionScope

对于所有这些模式,我忘记了一件事:
我如何实际实现数据库多访问保护问题
没有任何直接的 SQL 代码。

4

2 回答 2

4

我如何实际实施数据库多访问保护问题?

这是数据库引擎的工作。如果报告了任何问题,您的工作是确保您的应用程序正常失败。请参阅在数据库引擎中锁定

例如,我有一个包含一些记录的表。并且时不时发生一个 Web 请求(在控制器内部,然后是服务,然后是存储库)选择 SQL 表的最大行 > 假设 TicketId 列,然后在该表中插入另一行(该列值 + 1 )。

我在这里得到的印象是,考虑到您正在尝试复制它的行为,您似乎对您的数据库没有太大的信心。将您的字段设置为auto-increment,这应该可以解决您的问题。如果您确实必须实现自己的手动自动增量,那么您需要使用某种形式的锁定,因为您基本上拥有的是竞争条件,例如

private static object lockObject = new Object();

lock(lockObject)
{
    ... DB stuff
}

对于跨进程锁定,您可能需要查看一个命名的Mutex

于 2012-10-15T14:09:49.880 回答
1

为什么不使用单个表来表示票号并使用具有Seriliazable 事务隔离级别的事务?

int GetTicketNumber(bool shouldIncrement)
{

   if(shouldIncrement)
   {
     // use transaction with serilizable isolation level
     select and update
   }
   else
   {
     //just select
   }

}
于 2012-10-16T10:16:12.853 回答