如何在ASP.NET中处理数据并发?

时间:2010-03-25 13:45:54

标签: asp.net sql-server-2008 concurrency

我有一个应用程序,即同时由多个用户访问。 正在访问应用程序的用户获得相同的ID。

我在代码中所做的是,当他们创建新用户时,我从DB获取最大ID并将值增加到1。 这样他们就可以获得相同的ID。所以我在这种情况下面对并发。

如何解决这个问题。

当用户点击NewUser时,我需要显示不同的数字。

我使用的是SQL Server 2008和.NET 3.5以及C#.NET

提前致谢。

2 个答案:

答案 0 :(得分:3)

这是一个常见问题,但很容易解决..

  1. 更改您的用户表,以便userid是标识列
  2. 当您将新用户详细信息插入此表时,SQLServer将自动为您创建一个新的唯一用户ID
  3. 要获取为您创建的用户标识,请使用SCOPE_IDENTITY()函数
  4. 有关标识列以及如何检索新用户标识的更多信息,请查看本教程..

    SQLTeam - Understanding Identity Columns

    修改(根据以下评论)

    您当前获得重复用户ID的原因是,请求max(userid)和更新/插入新用户记录之间存在时间差。

    如果此延迟(请求和更新之间)为10分钟或10毫秒,则无关紧要,如果您的网站受到足够的打击,问题仍然会发生。

    通过使用标识列,SQLServer可以通过为您创建ID来有效地消除延迟。没有其他进程/用户可以被赋予相同的用户ID。

    尝试使用以下代码...

        /*Create Table*/
        CREATE TABLE TestTableSO (UserID INT IDENTITY(1,1), Username NVARCHAR(50))
    
        /*Insert some data, note that I'm not providing a UserID on my Insert*/
        INSERT INTO TestTableSO (Username) VALUES ('Joe')
        INSERT INTO TestTableSO (Username) VALUES ('Dan')
        INSERT INTO TestTableSO (Username) VALUES ('Fred')
        INSERT INTO TestTableSO (Username) VALUES ('Sam')
    
        /*Look at the data I've inserted*/
        SELECT * FROM TestTableSO
    
        /*Insert one more record*/
        INSERT INTO TestTableSO (Username) VALUES ('Roger')
    
        /*Look at the new UserID I have been given by SQL Server*/
        SELECT SCOPE_IDENTITY() as NewUserID
    
        /*Drop our table, only needed for testing*/       
        DROP TABLE TestTableSO
    

    从此代码中您将获得以下输出...

    UserID  Username
    ------------------
    1       Joe
    2       Dan
    3       Fred
    4       Sam
    
    NewUserID
    -----------
    5
    

    希望这是有道理的!再说一遍。使用Max(UserID)无法解决此问题 就像你一样。

    编辑#2

    创建UserID而不存储任何与UserID一起使用的信息是 BAD 的想法。由于用户将访问您的网站,获得用户ID但却未填写任何详细信息,您可能会更快地耗尽可用ID。如果他们是真正的用户,只为他们提供用户ID。

答案 1 :(得分:0)

您可以使用SCOPE_IDENTITY 这将解决您的问题!

<强>更新

如果您的ID不是IDENTITY列,您仍然可以在插入时从数据库中获取它 - 只需一次数据库调用。

例如:

解决方案1 ​​

DECLARE @MyID varchar -- could be an uniqueidentifier (GUID) as well
SET @MyID = GetNextID() -- a function that returns IDs

INSERT INTO [myTable] ([myData], [MyID])
VALUES(@myData, @MyID)

SELECT @MyID

解决方案2 :(对于SQL Server 2008)

INSERT INTO [myTable] ([myData], [MyID])
VALUES(@myData, GetNextID())
OUTPUT INSERTED.*

OUTPUT语句将返回新插入的记录 - 您也可以只返回带有OUTPUT INSERTED.MyID的ID列

-HTH