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

fix begin trasaction after reconnect #3679

Merged

Conversation

kalinin-k-a
Copy link
Contributor

@kalinin-k-a kalinin-k-a commented Sep 20, 2019

Q A
Type bug
BC Break no
Fixed issues

Summary

This is a small fix if we lose the connection and work with transactions after reconnect.
The code examples below demonstrate a problem:

/** Doctrine\DBAL\Connection $co */
$co->executeQuery('CREATE TABLE if not exists test11(test int not null)');
$co->executeQuery('truncate table test11');
$co->executeQuery('insert into test11 values (1)');
$co->beginTransaction();
$co->executeQuery('insert into test11 values (2)');
$v = $co->fetchAll('select * from test11');
$co->close(); // here we lost a connection or closed it for some reason
$co->beginTransaction(); /* p1 */
$co->executeQuery('insert into test11 values (33)');
$co->rollback(); /* p2 */
$v = $co->fetchAll('select * from test11'); // I expect the value 33 will not be selected from the table because it was rollbacked. But the transaction was not started on the line "p1" because of nestingLevel had not beed reset after open new connection.

@kalinin-k-a kalinin-k-a changed the title fix begin trasaction ofter reconnect fix begin trasaction after reconnect Sep 20, 2019
@morozov
Copy link
Member

morozov commented Sep 20, 2019

@kalinin-k-a please turn the scenario in the description into a test.

@kalinin-k-a
Copy link
Contributor Author

@kalinin-k-a please turn the scenario in the description into a test.

done

@greg0ire
Copy link
Member

Why are there 2 PRs for this? #3679 looks the same, but on another branch and without tests, which one is the right one?

@greg0ire
Copy link
Member

greg0ire commented Sep 21, 2019

Please squash your commits

fix begin trasaction ofter reconnect

Please explain in your commit message what was wrong, and why your changes fix that situation. Maybe

Reset transaction nesting level on connection loss

When the connection is lost, subsequent transactions will no longer be
nested because they are executed in a brand new session. Our internal
representation of the nesting should take this into account.

@kalinin-k-a
Copy link
Contributor Author

Why are there 2 PRs for this? #3679 looks the same, but on another branch and without tests, which one is the right one?

Another is into v2.5. I'll also write tests

@kalinin-k-a kalinin-k-a force-pushed the fix_begin_transaction_after_reconnect branch from f3d74d2 to d4bfeab Compare September 21, 2019 11:43
greg0ire
greg0ire previously approved these changes Sep 21, 2019
@greg0ire
Copy link
Member

Please associate your email address with your Github account, or change the email in your commits to an address already associated with it.

@kalinin-k-a
Copy link
Contributor Author

commits are squashed, email is changed. Thank you for reminding !

greg0ire
greg0ire previously approved these changes Sep 21, 2019
@kalinin-k-a
Copy link
Contributor Author

pushed again because mysql server had gone away during functional tests previously

$this->connection->beginTransaction(); // should connect, reset nesting level and increase it once
self::assertEquals(1, $this->connection->getTransactionNestingLevel());
$this->connection->commit();
self::assertEquals(0, $this->connection->getTransactionNestingLevel());
Copy link
Member

Choose a reason for hiding this comment

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

Please use the scenario from the description. The test as it's written now does not reflect the actual issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I’m not sure that scenario from description is good for test. It just shows one case that may be affected by nesting level issue. Also the result from the description may happen if for example commit works wrong.

I fixed nesting level reset, so i tested the same.

Do you insist on change test?

Copy link
Member

Choose a reason for hiding this comment

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

Without that case, it's not clear why we want to reset the transaction nesting level after establishing a connection. The level is an internal implementation detail of the DBAL, it doesn't have to be tested in a functional way but I'd rather have a functional case which relies on it. Even if it's just one case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.
Strange, but Insert statement fails the test now with "Table not found". Seems like table exist only before closing connection in testing environment. I'll look again a little later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. It was sqlite connection with memory=true. Please review once more

@kalinin-k-a kalinin-k-a force-pushed the fix_begin_transaction_after_reconnect branch 5 times, most recently from 4a3bc6b to 9b918da Compare September 22, 2019 09:19
@kalinin-k-a kalinin-k-a force-pushed the fix_begin_transaction_after_reconnect branch 4 times, most recently from 3f2e227 to 6456e69 Compare October 2, 2019 12:58
$this->connection->beginTransaction();
$connection->close(); // connection closed in runtime (for example if lost or another application logic)

$connection->beginTransaction(); // should connect, reset nesting level and increase it once
Copy link
Member

Choose a reason for hiding this comment

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

The comment doesn't seem relevant to what the test is about.

Copy link
Contributor Author

@kalinin-k-a kalinin-k-a Oct 7, 2019

Choose a reason for hiding this comment

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

"Should realy start the transaction, and the rollback() call below realy leads to rollback it " - better?

Copy link
Member

Choose a reason for hiding this comment

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

The transaction nesting level could be checked here too.

Copy link
Member

Choose a reason for hiding this comment

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

"Should realy start the transaction, and the rollback() call below realy leads to rollback it " - better?

Just remove the comment. The previous one says enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok,. done

Copy link
Member

Choose a reason for hiding this comment

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

Hm… it's still there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, it really was. Forgot to commit, sorry. Now it's realy done)

$connection->executeQuery('insert into test_nesting values (33)');
$connection->rollback();

self::assertEquals(0, $connection->fetchColumn('select count(*) from test_nesting'));
Copy link
Member

Choose a reason for hiding this comment

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

Should the transaction nesting level be checked here too?

Copy link
Member

Choose a reason for hiding this comment

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

Not really. The fact that the transaction was successfully rolled back is enough. The nesting level is an implementation detail in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should the transaction nesting level be checked here too?

The exact values of nestingLevel is completely tested in testTransactionNestingBehavior()

$this->connection->beginTransaction();
$connection->close(); // connection closed in runtime (for example if lost or another application logic)

$connection->beginTransaction(); // should connect, reset nesting level and increase it once
Copy link
Member

Choose a reason for hiding this comment

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

The transaction nesting level could be checked here too.

@kalinin-k-a kalinin-k-a force-pushed the fix_begin_transaction_after_reconnect branch from 6456e69 to 3df789f Compare October 11, 2019 08:29
morozov
morozov previously approved these changes Oct 11, 2019
When the connection is lost or is closed, subsequent transaction will no longer be nested because they started in a brand new session. Our internal representation of the nesting shold take this into account
@kalinin-k-a kalinin-k-a force-pushed the fix_begin_transaction_after_reconnect branch from 3df789f to b550879 Compare October 14, 2019 07:58
@morozov morozov dismissed SenseException’s stale review October 14, 2019 14:58

Transaction nesting level is tested in another test.

@morozov morozov merged commit 8012286 into doctrine:master Oct 14, 2019
@morozov
Copy link
Member

morozov commented Oct 14, 2019

Thank you @kalinin-k-a.

morozov added a commit that referenced this pull request Oct 14, 2019
@morozov morozov added this to the 2.9.3 milestone Oct 14, 2019
@morozov morozov self-assigned this Oct 14, 2019
rgrellmann added a commit to Rossmann-IT/dbal that referenced this pull request Apr 22, 2020
Release v2.9.3

[![Build Status](https://travis-ci.org/doctrine/dbal.svg?branch=v2.9.3)](https://travis-ci.org/doctrine/dbal)

This release fixes regressions introduced in previous releases and other bugs.

- Total issues resolved: **5**
- Total pull requests resolved: **14**
- Total contributors: **9**

**Regressions**

 - [3686: Fixed query result caching when `FetchMode::COLUMN` is used](doctrine#3686) thanks to @morozov and @Junker

 - [3456: Compare type class when comparing columns.](doctrine#3456) thanks to @garret-gunter and @cs278

**Other bugs**

 - [3679: fix begin trasaction after reconnect](doctrine#3679) thanks to @kalinin-k-a

 - [3547: Default column expressions do not work on SQL Server](doctrine#3547) thanks to @morozov

 - [3420: Index length can be a `string`: ensure that it is an integer when read by the `MySqlSchemaManager`](doctrine#3420) thanks to @leofeyer

**CI improvements and maintenance**

 - [3702: Updated SQL Server extensions to fix build failures on PHP 7.4](doctrine#3702) thanks to @morozov

 - [3662: Marked connection exception test incomplete on MySQL 8](doctrine#3662) thanks to @morozov

 - [3622: Switched from ibmcom/db2express-c to ibmcom/db2](doctrine#3622) thanks to @morozov

 - [3465: Replaced MySQL 5.7 installed from a PPA with an official Docker image](doctrine#3465) thanks to @morozov

 - [3454: CI: Test against PHP 7.4snapshot instead of nightly (8.0)](doctrine#3454) thanks to @Majkl578

 - [3452: Fixed AppVeyor build configuration and the issue on SQL Server](doctrine#3452) thanks to @morozov and @Majkl578

 - [3447: Replaced custom docker image for PostgreSQL with the official one](doctrine#3447) thanks to @morozov

 - [3407: CI: Test against MySQL 8.0 on Travis](doctrine#3407) thanks to @morozov

**PHP 7.4 support**

 - [3642: Fixed test failures on PHP 7.4](doctrine#3642) thanks to @morozov

# gpg: Signature made Sat Nov  2 23:20:42 2019
# gpg:                using RSA key 374EADAF543AE995
# gpg: Can't check signature: public key not found
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants