问题
My Razor 3 web app is creating multiple rows for the same foreign key Id, when multiple input comes in for the same Id, and I would like help on how to avoid this.
The SQL Server table stores data about records in another table (it's ratings users have given about certain things, where there is also a table of users and a table of rate-able things, so the ratings table has a foreign key id for user, a foreign key id for the thing rated, and a value for the rating). When no rating has been given, there is no row for that user id & thing id.
When a user rates a thing, the code calls the server, which checks to see if that user has rated that thing before, and if so, it updates the row, but if not, it creates a new row:
// Get the member's rating for the thing, or create it.
Member_Thing_Rating memPref = (from mip in _myEntities.Member_Thing_Rating
where mip.thingID == thingId
where mip.MemberID == memberId
select mip).FirstOrDefault();
if (memPref == null)
{
memPref = new Member_Thing_Rating();
memPref.MemberID = memberId;
memPref.thingID = thingId;
_myEntities.Member_Thing_Rating.AddObject(memPref);
}
Which works fine EXCEPT when the user sends two ratings for the same thing very quickly (which happens rather often), which results in the server creating two rows, because apparently it is multi-threaded and neither thread sees an existing row, so they both create a new one.
So... how can I avoid this?
- I assume I can somehow (?) tell SQL Server to make a constraint that combos of
memberID
andthingID
should be unique in this table, and then it would be SQL Server's job to auto-magically resolve the insertions and hopefully use the latest value.
or
- I imagine I could somehow (?) tell this routine to lock the DB or become single-threaded so that one completes adding a row before the next call to the same routine is allowed to execute.
I just don't know the syntax or UI/SQL steps to do either, despite a bit of looking. I think I prefer the thread lock solution, because I am more programmer than DB person, so I prefer my complexity in the code.
Thanks for any help!
回答1:
You could easily add a unique constraint to your SQL Server table to make sure you never get duplicates on your (memberID, thingID)
columns:
ALTER TABLE dbo.YourTableNameHere
ADD CONSTRAINT UQ_MemberID_ThingID UNIQUE(MemberID, ThingID)
Now, if your second connection tries to insert a row with values for (MemberID, ThingID)
that are already in the table, the INSERT
will fail, you'll get an exception which you can handle and e.g. get new values for one or both of those ID's.
来源:https://stackoverflow.com/questions/24464109/how-can-i-avoid-duplicate-rows-from-near-simultaneous-sql-adds