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] beginTransaction(): Reconnect if connection is lost #15511

Merged
merged 2 commits into from
Oct 13, 2016
Merged

[5.1] beginTransaction(): Reconnect if connection is lost #15511

merged 2 commits into from
Oct 13, 2016

Conversation

nhowell
Copy link
Contributor

@nhowell nhowell commented Sep 19, 2016

I couldn't figure out how to get PHPUnit to do what I wanted in order to write a test for this. There doesn't seem to be a way to do

$pdo->expects($this->once())->method('beginTransaction')->will($this->throwException(new ErrorException('MySQL server has gone away')));

for the first run of $this->getPdo()->beginTransaction() but then expect a second run of $this->getPdo()->beginTransaction() to run successfully.

Let me know if you have any suggestions on how to test this.

This PR should, at least partly, fix issue #15179.

If we're beginning a new transaction, we should check if the exception
was caused by a lost connection. If so, then try again (like we do when
when running a query/statement).

We won't do a reconnect if it is a nested transaction though, because if
the connection has been lost then the transaction has already been
rolled back. (Queries/statements already won't try to reconnect if
they're inside a transaction, either.)
@nhowell nhowell changed the title beginTransaction(): Reconnect if connection is lost [5.1] beginTransaction(): Reconnect if connection is lost Sep 19, 2016
@GrahamCampbell
Copy link
Member

We need another test please.

@nhowell
Copy link
Contributor Author

nhowell commented Sep 20, 2016

We need another test please.

I couldn't figure out how to write a test for this. Any tips?

@taylorotwell
Copy link
Member

DIdn't we just revert something like this?

@nhowell
Copy link
Contributor Author

nhowell commented Sep 20, 2016

DIdn't we just revert something like this?

Are you possibly referring to 0b94001?

@taylorotwell
Copy link
Member

Yeah, that might be what is jogging my memory.

@nhowell
Copy link
Contributor Author

nhowell commented Sep 22, 2016

I've added a couple tests.

@nhowell
Copy link
Contributor Author

nhowell commented Sep 23, 2016

Ping @taylorotwell. So what do you think? 😄

@taylorotwell
Copy link
Member

I dont know it seems like there would be a better way to do this without changing so much code and logic.

@nhowell
Copy link
Contributor Author

nhowell commented Sep 28, 2016

I dont know it seems like there would be a better way to do this without changing so much code and logic.

I don't follow. Could you elaborate? There is very little code and logic changed. The only real logic change is this bit here that checks if the exception was caused by a lost connection, if so it reconnects then tries to begin the transaction again.

if ($this->causedByLostConnection($e)) {
    $this->reconnect();
    $this->pdo->beginTransaction();
} else {
    throw $e;
}

Additionally, I moved the ++$this->transactions; to the end of the method to simplify the code (so that we no longer need to --$this->transactions; if there was an error).

Excluding tests and PHPDoc fixes, this PR is really just 11 additions and 8 deletions.

@fredsted
Copy link

fredsted commented Oct 8, 2016

We've been having this issue on workers, they sometimes fail in beginTransaction(), and because we're using the --daemon flag, the workers stay up, continuing to make exceptions. So sometimes we'll have to go and restart all the jobs, and do a queue:retry all, then they'll run because the connection was reestablished. Right now we've tried fixing this by reconnecting before every job, but that seems excessive to me.

I think this would solve our problems!

@taylorotwell taylorotwell reopened this Oct 8, 2016
@taylorotwell
Copy link
Member

I'll reopen it so I can take a fresh look.

@iget-esoares
Copy link
Contributor

@taylorotwell Will this fix be implemented on L5.2?

@GrahamCampbell
Copy link
Member

Unlikely. Only 5.1 is LTS, not 5.2.

@lopn
Copy link

lopn commented Feb 13, 2017

what's time to revised release version? I found that the lasted version of 5.1 not include this change!

@barryvdh
Copy link
Contributor

barryvdh commented Feb 22, 2017

Is this related to #17785 ?
Should commit etc also reconnect if failed?

@nhowell nhowell deleted the transaction-reconnect-if-lost-connection branch February 22, 2017 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants