Closed intellent closed 1 year ago
I think this is something you'll want to handle in your app, rather than in the package.
You can catch the exception and generate a new UUID yourself, but then you'd be making an assumption that it's definitely the UUID that's duplicated and not some other unique constraint in the table (that we won't know about in the package).
In short, yes, something like the above will suffice. It's contrived, but probably the simplest way of handling it, depending on whether this is repeated elsewhere.
try {
$model->save();
} catch (QueryException $e) {
$model->uuid = Str::uuid()->__toString();
$model->save();
}
UUIDs are intended to be very difficult to collide, so I'm curious if this is something you've run in to, or if it's something you're catering to just in case?
I think this is something you'll want to handle in your app, rather than in the package.
Absolutely. I didn’t want to imply otherwise. 🙂
So I need to set a new UUID manually via Str::uuid()
? Is laravel-model-uuid using Str::uuid()
internally, as well? I was hoping to use the same mechanism, the original UUID has been created with.
UUIDs are intended to be very difficult to collide, so I'm curious if this is something you've run in to, or if it's something you're catering to just in case?
The latter. Just want to make my code as robust as possible.
There are lots of retry options. I find the topic interesting, but not in the least with regard to UUIDv4 collisions.
Start by making sure you have a unique constraint on your uuid
column so your code it throws an exception when a collision (statistically never) occurs. In your migration:
$table->unique('uuid');
Then pick one of these:
sync
queue driver to avoid asynchronous job queuing, and keep the retry logic in the same process.)Yes, it's possible to get a collision. But, in the time since UUIDv4 was invented, maybe a handful of collisions have occurred across the entirety of computing on the planet. I don't mean UUIDv4s have collided in the same system either. For example, it's possible Google has generated a UUIDv4 for an email in Gmail, and Apple may have generated the same one for an iMessage.
But let's say you're the unluckiest UUIDv4 generator in the next 80 millennia and you see a few collisions. So what? You have a couple users affected? They can presumably retry whatever operation that broke, and move on.
As a production implementation, I think it's likely to cause more bugs than a collision or two in the lifetime of an app (eg. 10 years). I'd decline a code review if I saw something like this. As an exercise in retry logic, I think it's fun though.
Foremost: Great project. This should make it into the core!
Although very unlikely, it’s still theoretically possible for
GeneratesUuid
to produce duplicates. So we have to account for that when persisting a model to a unique database field.What is the recommended way to make laravel-model-uuid generate a new UUID in such cases? Is it sufficient to just trigger
$model->save()
again? Or do I need to reset the model somehow (e.g., by setting the UUID field tonull
first?