简体   繁体   中英

Update activity time on concurrent connections

I have a api and on each request to this api i save/update the user activity.

But the problem is, when there is 5 concurrent connections to the api from the same user, i get this:

Violation of PRIMARY KEY constraint 'PK_user_act'. Cannot insert duplicate key in object 'user_activity

The duplicate key value is (2015-06-11, 76146, 1). The statement has been terminated.*

I have this sql:

if not exists (select 1 from user_activity where user_id = @UserNr and stat_date = CAST(GETUTCDATE() AS DATE))
   insert into user_activity(user_id, stat_date, start_date, end_date)
VALUES
(@UserNr, GETUTCDATE(), GETUTCDATE(), GETUTCDATE())
ELSE
   UPDATE user_activity set end_date = GETUTCDATE() where user_id = @UserNr and stat_date = CAST(GETUTCDATE() AS DATE)

I use ADO.NET and a SP to update the user activity. I think this sql is running at the same time, and the first request is saved, and the other 4 get this error.

What can i do to fix this?

UPDATE: We using Azure SQL, v12 for this. (We have 1-1,5 m connections to this api / day)

You're in luck! Azure SQL uses SQL Server, which supports MERGE :

MERGE User_Activity AS target
USING (SELECT @UserNr, GETUTCDATE()) AS source (userNr, rightNow)
      ON (target.userId = source.userNr)
WHEN MATCHED THEN 
     UPDATE SET end_date = source.rightNow
WHEN NOT MATCHED THEN
     INSERT (user_id, stat_date, start_date, end_date)
            VALUES (source.userNr, source.rightNow, source.rightNow, source.rightNow)

(not tested - no sample data)


Note, though this solves this particular issue, I agree with @The Bojan - you have a table with a multi-part key. Probably what you should do is change your table to look something like this:

 CREATE TABLE User_Activity (userId INTEGER, lastSeenAt DATETIME2) 

... and just INSERT to it (and don't use any transactions). At the end of each day you can easily roll up all the records into your current table, then clear it out.

考虑在SP中使用事务 ,以避免在并发执行之间混淆SQL指令,并确保IF语句的检查每次都能获取正确的数据以进行检查

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM