-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[10.x] Revival of the reverted changes in 10.25.0: firstOrCreate
updateOrCreate
improvement through createOrFirst
+ additional query tests
#48637
[10.x] Revival of the reverted changes in 10.25.0: firstOrCreate
updateOrCreate
improvement through createOrFirst
+ additional query tests
#48637
Conversation
… methods (laravel#48531)" This reverts commit 408a3e3.
397211a
to
e4efdc3
Compare
e4efdc3
to
ebc9ba1
Compare
I honestly suggest to just leave things be. I also don't know what this is fixing again? |
@driesvints If you have any comments, please see #48567. I personally emailed @taylorotwell and asked him about the policy and he agreed that as long as we add a test it should be fine.
|
40797ac
to
877e32f
Compare
877e32f
to
e5735c4
Compare
3141fb7
to
62455dd
Compare
Test/has many through
a025850
to
30d4627
Compare
0c5ce5f
to
fab4ee3
Compare
@taylorotwell @crynobone @driesvints @tonysm @ralphjsmit @ryanldy @trevorgehman @SakiTakamachi @fuwasegu Please review the changes. Thank you in advance. |
@mpyw if we rely on a unique constraint and the model's attributes doesn't not include the primary key of the table. And the attributes used let's call it |
@morloderex This is not a breaking change. It works as follows.
The |
Without a unique constraint on the table |
@driesvints Essentially it solves race conditions. In high concurrency environments we can't rely on We have for a long time implemented a workaround like this by extending the Builder:
This strategy of catching framework/src/Illuminate/Database/Eloquent/Builder.php Lines 580 to 587 in fcceb52
|
I don't envy Taylor on this PR at all 😅 [✗] This is a significant change to one of Laravel's most important modules (Eloquent). |
I don't understand why it needs to be replaced. |
@deleugpn You do not need to replace them.
Generally, continuing to use |
They have different use-cases. If 95% of the time the record already exists, then |
@trevorgehman Exactly the same opinion with you 😄 |
We also hope that this change will be covered in Laravel News. It is not a BC, but I think it is significant to let people know. |
19f8b61: Some of ❯ git merge upstream/10.x
Merge made by the 'ort' strategy.
src/Illuminate/Console/GeneratorCommand.php | 9 ++++--
src/Illuminate/Database/Concerns/BuildsQueries.php | 35 ++++++++++++++++++++++-
src/Illuminate/Database/Concerns/ManagesTransactions.php | 11 ++++----
src/Illuminate/Database/DatabaseTransactionsManager.php | 30 +-------------------
src/Illuminate/Database/Eloquent/Model.php | 1 +
src/Illuminate/Database/Query/Grammars/Grammar.php | 3 +-
src/Illuminate/Foundation/Application.php | 2 +-
src/Illuminate/Foundation/Testing/DatabaseTransactionsManager.php | 2 +-
src/Illuminate/Mail/Transport/SesTransport.php | 4 +--
src/Illuminate/Mail/Transport/SesV2Transport.php | 4 +--
src/Illuminate/Support/Str.php | 19 ++++++++++++-
src/Illuminate/View/Compilers/BladeCompiler.php | 4 +--
tests/Database/DatabaseConnectionTest.php | 15 ++++++++++
tests/Database/DatabaseEloquentModelTest.php | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Database/DatabaseQueryBuilderTest.php | 20 +++++++++++++
tests/Database/DatabaseQueryGrammarTest.php | 44 +++++++++++++++++++++++++++++
tests/Integration/Console/GeneratorCommandTest.php | 28 ++++++++++++++++++
tests/Integration/Database/EloquentTransactionWithAfterCommitTests.php | 48 +++++++++++++++++++++++++++++++
tests/Integration/Database/QueryBuilderTest.php | 38 +++++++++++++++++++++++++
tests/Integration/Queue/ThrottlesExceptionsWithRedisTest.php | 15 +++++-----
tests/Mail/MailSesTransportTest.php | 20 +++++++++++++
tests/Mail/MailSesV2TransportTest.php | 20 +++++++++++++
tests/Support/SupportStrTest.php | 2 ++
23 files changed, 467 insertions(+), 57 deletions(-)
create mode 100644 tests/Database/DatabaseQueryGrammarTest.php
create mode 100644 tests/Integration/Console/GeneratorCommandTest.php |
firstOrCreate
updateOrCreate
improvement through createOrFirst
+ additional query tests firstOrCreate
updateOrCreate
improvement through createOrFirst
+ additional query tests
Impressive refinement of |
Thanks - this is probably our last attempt at this. 😬 |
…pdateOrCreate` improvement through `createOrFirst` + additional query tests (laravel#48637) * Revert "[10.x] Revert from using `createOrFirst` in other `*OrCreate` methods (laravel#48531)" This reverts commit 408a3e3. * test: 💍 Add `Builder::createOrFirst()` snapshot tests * test: 💍 Add `Builder::firstOrCreate()` snapshot tests * test: 💍 Add `Builder::updateOrCreate()` snapshot tests * test: 💍 Add test stubs for `DatabaseEloquentHasManyTest` * test: 💍 Add `HasMany::createOrFirst()` snapshot tests * test: 💍 Add `HasMany::firstOrCreate()` snapshot tests * test: 💍 Add `HasMany::updateOrCreate()` snapshot tests * test: 💍 prepare HasManyThrough test * test: 💍 Add HasManyThrough::CreateOrFirst() snapshot tests * test: 💍 Add HasManyThrough::firstOrCreate() snapshot test * test: 💍 Add HasManyThrough::updateOrCreate() snapshot test * refactor: 💡 use createOrFirst in firstOrCreate * test: 💍 fix test * style: 💄 Apply StyleCI fixes * docs: ✏️ Add missing FIXME comments * refactor: 💡 Omit verbose arguments * test: 💍 Rename `DatabaseEloquentHasManyThroughTest` with fixes * test: 💍 Add `BelongsToMany::createOrFirst/firstOrCreate` tests * test: 💍 Extract `DatabaseEloquentHasManyTest` cases with fixes * test: 💍 Extract `DatabaseEloquentBuilderTest` cases with fixes * test: 💍 refactoring * test: 💍 Add `BelongsToMany::updateOrCreate` snapshot tests --------- Co-authored-by: fuwasegu <admin@fuwasegu.com>
@nunomaduro Okay, I'll check it out |
Prior Discussion
What Changes?
This PR unreverts #48531 and revives
firstOrCreate
updateOrCreate
enhancement undercreateOrFirst
. They were unreliable in previous versions. In high-load applications, unique key constraint errors would occur even when checking for the existence of a record beforehand. The purpose of refactoring withcreateOrFirst
internally is to catch this and retry automatically.Actual Implementation Changes
HasManyThrough::firstOrCreate
to usecreateOrFirst
. This was a previously overlooked point.Coverages
Builder::createOrFirst
by @mpywBuilder::firstOrCreate
by @mpywBuilder::updateOrCreate
by @mpywHasMany::createOrFirst
by @mpywHasMany::firstOrCreate
by @mpywHasMany::updateOrCreate
by @mpywHasManyThrough::createOrFirst
by @fuwasegu + @mpywHasManyThrough::firstOrCreate
by @fuwasegu + @mpywHasManyThrough::updateOrCreate
by @fuwasegu + @mpywBelongsToMany::createOrFirst
by @mpywBelongsToMany::firstOrCreate
by @mpywBelongsToMany::updateOrCreate
by @mpywNotes
Some
FIXME
comments are remaining.These indicate a problem with duplicate and useless conditions being given when retrying the
SELECT
, but do not significantly bother with the operation. Attempting to fix this usingclone
may yield some unexpected effects due to theBuilder
mutableness. Therefore, we'd like to recognize this as a known issue and leave it out of the scope of this PR.@tonysm If you think you can fix this problem, could you please submit another PR? Thank you in advance.