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

[5.1] Never retry query if failed within transaction #12929

Merged
merged 2 commits into from
Mar 30, 2016
Merged

[5.1] Never retry query if failed within transaction #12929

merged 2 commits into from
Mar 30, 2016

Conversation

themsaid
Copy link
Member

Here's the scenario:

DB::beginTransaction();
DB::insert(); // QueryException thrown

This causes the following to happen

  1. Connection::tryAgainIfCausedByLostConnection() is called inside Connection::run()
  2. Connection::reconnect() is called inside tryAgainIfCausedByLostConnection()
  3. DatabaseManager::reconnect() is called
  4. DatabaseManager::disconnect() is called inside DatabaseManager::reconnect()
  5. Connection::disconnect() is called inside DatabaseManager::disconnect()
  6. Connection::setPdo(null) is called inside Connection::disconnect()

Inside setPDO():

if ($this->transactions >= 1) {
    throw new RuntimeException("Can't swap PDO instance while within transaction.");
}

So while there's a transaction open a retry can never happen, the result of this behaviour is that a RuntimeException is thrown hiding the QueryException which contains useful information about the problem.

This PR checks if there's a transaction open when a QueryException is thrown, if so it just throws the exception again for developers to handle it properly and never retries the query because it'll fail anyway.

@GrahamCampbell
Copy link
Member

This will break apps?

@themsaid
Copy link
Member Author

@GrahamCampbell
QueryException extends PDOException which extends RuntimeException. So when we throw a QueryException those catching the old RuntimeException are safe. Unless they do get_class($e) for example.

Not sure if this would be considered breaking or not.

@taylorotwell taylorotwell merged commit 933c009 into laravel:5.1 Mar 30, 2016
@themsaid themsaid deleted the never-try-within-transaction branch April 1, 2016 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants