title: Distributed locking vs constraint violation exception handling for control flow
body: <p>I have a distributed system that needs to perform an atomic database operation. In essence, the application needs to perform a <code>find or create</code>.</p>
  
  <p>I can think of two options:</p>
  
  <p>A) Use a distributed lock to ensure that the operation is atomic across processes/systems. Check if the record exists. Get or create the record accordingly.</p>
  
  <p>B) Always attempt to insert the record. Allow the database to raise a unique constraint violation error and catch the exception in the application. If an exception is raised, then it exists so get the record instead.</p>
  
  <p>Option A seems more <em>correct</em> obviously but which is more performant? </p>
  
  <p>Using exception handling for control flow is smelly but is it really that terrible? I feel like option B is more readable and easier to reason about. Plus it doesn't require a lock on the database.</p>
  
  <p>Can you anyone give me a concrete reason <em>not</em> to use option B with concrete evidence?</p>
  
  <p>Thanks!</p>