Here is a simple design, that simplifies handling "collisions". You only need to UPDATE one row for this method to work:
UserEmailAddresses Table
------------------------
YourPKHere <whatever you have, identity?>
UserId <whatever you have>
EmailAddressId <whatever you have>
DisplaySeq INT
LastChgDate datetime
SELECT * FROM UserEmailAddresses ORDER BY DisplaySeq ASC, LastChgDate DESC
EDIT sample code
DECLARE @UserEmailAddresses table
(
YourPKHere int identity(1,1) primary key
,UserId int
,EmailAddressId varchar(100)
,DisplaySeq INT
,LastChgDate datetime
)
--existing data
INSERT INTO @UserEmailAddresses values (1,'[email protected]',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (1,'[email protected]',2,'2/2/2009')
INSERT INTO @UserEmailAddresses values (1,'[email protected]',3,'3/3/2009')
INSERT INTO @UserEmailAddresses values (2,'[email protected]',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (2,'[email protected]',2,'2/2/2009')
--application updates one row, no locking or blocking
update @UserEmailAddresses set DisplaySeq=1,LastChgDate=getdate() where UserId=1 and EmailAddressId='[email protected]' --could say WHERE YourPKHere=n, but you don't give your complete table schema
--display the emails in proper order, with displayable continuous row numbers
SELECT
*, ROW_NUMBER() over(partition by UserId order by DisplaySeq ASC,LastChgDate DESC) AS ActualDuisplaySeq
FROM @UserEmailAddresses
WHERE UserId=1
--display the e-mails in proper order
SELECT * FROM @UserEmailAddresses Where UserId=1 ORDER BY DisplaySeq ASC, LastChgDate DESC