Checking @@ROWCOUNT failing
I'm not sure why you're using a variable, but you need to protect multiple statements with a transaction. What's happening is two users are calling the procedure at the same time, both are getting rowcount = 0, and then they're both trying to insert as a result.
set transaction isolation level serializable;
begin transaction;

update dbo.table1
  set value = @value
  where id = @id;

if (@@ROWCOUNT = 0)
begin
  insert dbo.table1(id, value1,value2...)
    values(@id, @value1, @value2...);
end 

commit transaction;

I blogged about this since writing this answer:

Please stop using this UPSERT anti-pattern