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

Implement transaction savepoints #1816

Merged
merged 11 commits into from
Dec 19, 2024
Merged

Conversation

henadzit
Copy link
Contributor

@henadzit henadzit commented Dec 17, 2024

Description

This PR:

  • Implements savepoints for Postgres, MySQL, MSSQL and Sqlite
  • Improves test isolation. Since Tortoise.init makes global changes, in some cases test runs were impacting each other.
  • Updates the docs and add a warning about starting concurrent tasks from within a transaction and starting nested transactions inside it.
  • Updates CHANGELOG to plan for a major release 0.23 since the transaction behavior is going to change

Motivation and Context

Before the changes any exception within a transaction block, even nested, would rollback the whole transaction. Savepoints allow more granularity when handling errors:

    async with in_transaction():
        await MyModel.create(name='foo')
        try:
            # this block will create a savepoint
            async with in_transaction():
                await MyModel.create(name='bar')
                # this will rollback to the savepoint, meaning that
                # the 'bar' record will not be created, however,
                # 'foo' will be created
                raise Exception()
        except Exception:
            pass

How Has This Been Tested?

  • make ci
  • running local app

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@coveralls
Copy link

coveralls commented Dec 18, 2024

Pull Request Test Coverage Report for Build 12409678196

Details

  • 123 of 144 (85.42%) changed or added relevant lines in 9 files are covered.
  • 3 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.3%) to 90.14%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tortoise/backends/oracle/client.py 1 2 50.0%
tortoise/backends/asyncpg/client.py 11 13 84.62%
tortoise/backends/psycopg/client.py 18 20 90.0%
tortoise/backends/odbc/client.py 4 7 57.14%
tortoise/backends/mssql/client.py 26 30 86.67%
tortoise/backends/sqlite/client.py 21 25 84.0%
tortoise/backends/mysql/client.py 26 31 83.87%
Files with Coverage Reduction New Missed Lines %
tortoise/backends/odbc/client.py 1 96.94%
tortoise/init.py 2 94.81%
Totals Coverage Status
Change from base Build 12342471369: -0.3%
Covered Lines: 6368
Relevant Lines: 6949

💛 - Coveralls

@henadzit henadzit changed the title WIP Implement transaction savepoints Implement transaction savepoints Dec 18, 2024
@henadzit henadzit marked this pull request as ready for review December 18, 2024 13:01
Copy link
Member

@abondar abondar left a comment

Choose a reason for hiding this comment

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

Thanks, it's cool feature

CHANGELOG.rst Outdated
====
0.22.3 (unreleased)

0.23.1 (unreleased)
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it be 0.23.0?

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.

``atomic()`` and ``in_transaction()`` can be nested. The inner blocks will create transaction savepoints,
and if an exception is raised and then caught outside of a nested block, the transaction will be rolled back
to the state before the block was entered. The outermost block will be the one that actually commits the transaction.
The savepoints are supported for Postgres, SQLite, MySQL and SQLite. For other databases, it is advised to
Copy link
Member

Choose a reason for hiding this comment

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

2 times for SQlite?

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 :)

@henadzit henadzit merged commit 433e302 into tortoise:develop Dec 19, 2024
8 checks passed
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.

3 participants