Skip to content
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

Catch UniqueConstraintViolationException inside insertIfNotExist #12371

Conversation

This is the most common case for the usage of this method.

See also #12369 and the linked tickets.

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
@MorrisJobke
Copy link
Member Author

@obel1x This is basically the more general approach.

Copy link
Member

@blizzz blizzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code looks good and makes sense

Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

@nickvergessen
Copy link
Member

Well this basically "breaks" the case when you have a unique key which is not the pattern you are trying to match, but that does not sound like a valid usecase to me, so I'm fine with this.

Let's hope it finally kills these reports.

@MorrisJobke
Copy link
Member Author

Well this basically "breaks" the case when you have a unique key which is not the pattern you are trying to match, but that does not sound like a valid usecase to me, so I'm fine with this.

That's also what I thought, I will check if any existing app does that, but I don't expect it.

@kesselb
Copy link
Contributor

kesselb commented Nov 9, 2018

the case when you have a unique key which is not the pattern you are trying to match, but that does not sound like a valid usecase to me

😕 If this is not a valid usecase and unique key are working for all supported dbms why do you still use this "fake" atomic insert approach here?

try {
    $connection->insert('blubba');
} catch(UniqueConstraintViolationException $e) {

}

Is the above not working? Do i miss something? (I have to admit, I feel a little stupid right now 🤣)

@MorrisJobke
Copy link
Member Author

Is the above not working? Do i miss something? (I have to admit, I feel a little stupid right now 🤣)

I guess it's fine then. The only problem with this is that the unique index needs to be in place. WIth the other logic it's also detected if the unique index is not in place. So we maybe want to go for the "first select and if no result insert with a wrapping of the insert".

@nickvergessen
Copy link
Member

@danielkesselberg well you can use insertIfNotExists without having a unique key on your table.

@MorrisJobke
Copy link
Member Author

@danielkesselberg well you can use insertIfNotExists without having a unique key on your table.

The only problem with this approach seems to be this deadlock somehow. But I have no idea how to reliably trigger this one in a test environment.

@MorrisJobke
Copy link
Member Author

Also thinking about this a bit and the better approach to this would be to deprecate this method and do this just properly in the application logic:

try {
  $db->insert(...);
} catch(UniqueConstraintViolationException $e) {
  // already in there
}

Then the developer does not trust us to do this correct, but is properly aware of the situation and just does it in the right way.

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
@MorrisJobke
Copy link
Member Author

I would still go for this PR here and backport it. Then also replace the existing occurrences. I added the deprecation message as well to this PR.

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
@MorrisJobke
Copy link
Member Author

I fixed the unit test. This is now good to go into 15. I would do this for 15 only and do separate PRs, that replace the insertIntoIfNotExist with a proper handling in the application itself, which then also could be more easily ported to older versions.

@MorrisJobke MorrisJobke merged commit 859dd1e into master Nov 12, 2018
@MorrisJobke MorrisJobke deleted the bugfix/12369/catch-unique-constraint-violation-exception-in-insertIfNotExist branch November 12, 2018 12:41
MorrisJobke added a commit that referenced this pull request Nov 12, 2018
* fixes #9305 by not being prone to the race condition in insertIfNotExists
* fixes #6899 by not using a query that can result in a deadlock
* replaces the insertIfNotExists call with an insert which is wrapped into a try-catch block
* followup to #12371

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
MorrisJobke added a commit that referenced this pull request Nov 12, 2018
…al config tables

* followup to #12371

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
MorrisJobke added a commit that referenced this pull request Nov 13, 2018
* fixes #9305 by not being prone to the race condition in insertIfNotExists
* fixes #6899 by not using a query that can result in a deadlock
* replaces the insertIfNotExists call with an insert which is wrapped into a try-catch block
* followup to #12371

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
MorrisJobke added a commit that referenced this pull request Nov 13, 2018
* fixes #9305 by not being prone to the race condition in insertIfNotExists
* fixes #6899 by not using a query that can result in a deadlock
* replaces the insertIfNotExists call with an insert which is wrapped into a try-catch block
* followup to #12371

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
MorrisJobke added a commit that referenced this pull request Nov 14, 2018
…al config tables

* followup to #12371

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment