preventing duplicate inserts?

Apologies if this looks like a dupe. I posted something similar a
couple days ago but I can't seem to find the thread. In my profile it
claims I posted the thread, but then won't give me a link to it.
anyway...

I have 2 ruby processes that are chugging along adding or updating
email addresses from different sources. Occasionally, they both see the
same email address at the same time. They're inserting into a table
that has a unique index on the email address.

So I have code along the lines of:

def address_seen(newaddr)
  transaction
    addrinfo = AddrInfo.find(:addr => newaddr)
    if addrinfo == nil
      addrinfo = AddrInfo.create!(:addr => newaddr, ...)
    end
  end
end

The problem is this doesn't prevent a duplicate insert error (resulting
in Mysql::Error: #23000Duplicate entry).

How, using rails, can I make 2 or more ruby processes coordinate
through the DB so that they don't try to insert the same row more than
once?

Apologies if this looks like a dupe. I posted something similar a
couple days ago but I can't seem to find the thread. In my profile it
claims I posted the thread, but then won't give me a link to it.
anyway...

I have 2 ruby processes that are chugging along adding or updating
email addresses from different sources. Occasionally, they both see the
same email address at the same time. They're inserting into a table
that has a unique index on the email address.

So I have code along the lines of:

def address_seen(newaddr)
transaction
  addrinfo = AddrInfo.find(:addr => newaddr)
  if addrinfo == nil
    addrinfo = AddrInfo.create!(:addr => newaddr, ...)
  end
end

The problem is this doesn't prevent a duplicate insert error (resulting
in Mysql::Error: #23000Duplicate entry).

How, using rails, can I make 2 or more ruby processes coordinate
through the DB so that they don't try to insert the same row more than
once?

Wrap your 'create' line in a begin/rescue/end block and catch the error coming from mysql...

Although the error you give above suggests that mysql is *NOT* allowing duplicate entries. If you simply wanted to shut it up just do:

begin
   addrinfo = AddrInfo.create!(:addr => newaddr, ...)
rescue
   nil
end

and get rid of the transaction all together...