违反插入时的PRIMARY KEY约束

Tom*_*len 1 c# linq conflict primary-key

我有一个简单的表:

IPAddress (PK, string)
Requests (int)
Run Code Online (Sandbox Code Playgroud)

这是一个洪水限制器.每分钟删除表数据.每个页面请求,Requests给定的计数增量IPAddress.

由于我们的产品和网站的性质,我们确实遭受了一些偶然/有意的有效DDOS,因此它运行良好,我们的网站性能显着提高.

唯一的问题是,当IP因某种原因每分钟向我们的网站发送数千个请求时,我们会突然出现这些错误:

违反PRIMARY KEY约束'PK_v2SiteIPRequests'.无法在对象'dbo.v2SiteIPRequests'中插入重复键.重复键值为([IP_ADDRESS]).该语句已终止.

制作插入的代码是:

/// <summary>
/// Call everytime a page view is requested
/// </summary>
private static void DoRequest(string ipAddress)
{
    using (var db = new MainContext())
    {
        var rec = db.v2SiteIPRequests.SingleOrDefault(c => c.IPAddress == ipAddress);
        if (rec == null)
        {
            var n = new v2SiteIPRequest {IPAddress = ipAddress, Requests = 1};
            db.v2SiteIPRequests.InsertOnSubmit(n);
            db.SubmitChanges();
        }
        else
        {
            rec.Requests++;
            db.SubmitChanges();

            // Ban?
            if (rec.Requests >= Settings.MAX_REQUESTS_IN_INTERVAL)
            {
                BanIP(ipAddress);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

处理此异常的最佳方法是什么,为什么会被抛出?是try catch这里最好的吗?

nvo*_*igt 5

如果您同时收到两个请求,则会发生以下情况:

Request one: is it in the database?
Request two: is it in the database?

Request one: No, not yet
Request two: No, not yet

Request one: INSERT
Request two: INSERT

Request one: WORKS
Request two: FAILS (already inserted a split second before)
Run Code Online (Sandbox Code Playgroud)

这里没有什么可以做的,但抓住异常并优雅地处理它.也许通过使用简单的"再试一次"逻辑.