Laravel v10.20 came out with a brand-new method called
createOrFirst(), contributed by Tony Messias, which might be a little confusing because Laravel already had a
firstOrCreate(). What are the differences? Why do we need two methods for this? Let's take a look...
createOrFirst() method is designed to do better in highly concurrent environments and helps reduce race conditions, but requires a unique constraint on the database.
createOrFirst, we invert this flow and rely on the tables having a
UNIQUEconstraint. So, first, we attempt to create the record, and if we get an exception back from the database and identify that it's a unique constraint violation, we attempt to find the matching record instead. This way, concurrent processes may rely on the ACID characteristics of the database and never have to worry about that race condition again.
You can find out more details on the pull request.
firstOrCreate was the original method, and here is how it's currently defined in the docs:
The firstOrCreate method will attempt to locate a database record using the given column/value pairs. If the model can not be found in the database, a record will be inserted with the attributes resulting from merging the first array argument with the optional second array argument
What is also cool about this new method is that now the original
firstOrCreate method uses the new
createOrFirst one under the hood. So it goes by:
- attempts to find
- if missing, attempts to create
- if UNIQUE violation happens, attempt another find because we ran into that race condition
Which to use?
I would say in most apps, the original
firstOrCreate is fine, and you'd really only want to use
createOrFirst when you are in a concurrent environment with tons of traffic.