【发布时间】:2012-10-15 14:05:37
【问题描述】:
我正在开发 MVC Web 应用程序。
这意味着我正在创建视图、模型、视图模型。我使用 linq-to-sql 作为数据库提供程序,我已经实现了自定义 Unit-of-Work 模式,以及看起来完美的数据源、存储库和服务模式(在我的实现中)并且与直接的 SQL 代码完全分离。实际上,来自任何为单元测试而设计的数据库,因此我可以使用内存数据源测试我的应用程序,而不会影响数据库。
最终我遇到了一个问题:我没有针对跨线程(或跨进程,因为据我所知,IIS 可以使用单个 Web 应用程序创建多个应用程序域)操作的保护。
例如,我有一个包含一些记录的表。并且不时发生一个 Web 请求(在控制器内部,然后是服务,然后是存储库)选择 SQL 表的最大行,比如说 TicketId 列,然后在该表中插入另一行 (that column value + 1)。
如果两个或多个线程或进程做同样的事情,重复的值可能会出现在数据库中。前段时间,当我的 web 应用程序更小时,我在 SELECT 语句中使用了直接 SQL 代码和简单的 UPDLOCK TransactionScope using 块锁定了我正在修改的记录(或其他任何东西)阻止所有其他数据库客户端等到我完成。
对于所有这些模式,我忘记了一件事:
我如何实际实施数据库多访问保护问题?
没有任何直接的 SQL 代码。
【问题讨论】:
-
数据库身份仍应由数据库管理,让它做+1。它的算法已经过很好的测试:)
-
什么算法?我的存储库可以同时运行,将重复值生成到数据库中,并在同一个项目中工作两次。当两个相同的网络请求进来时就会发生这种情况。
-
如果您让数据库生成 ID,则不会。这就是 SQL Server 的 IDENTITY 特性存在的原因。
-
我并不总是需要 +1。在其他 50% 的情况下,我需要将
TicketId的值保持在与之前所有增加id列相同的最大值(你们都在寻找我的身份)
标签: c# sql-server design-patterns linq-to-sql multithreading