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

More logging when cannot use transaction #2

Draft
wants to merge 6 commits into
base: v0.25.0-crdb
Choose a base branch
from

Conversation

jlrobins
Copy link

@jlrobins jlrobins commented Jul 28, 2022

This PR / branch isn't really for PRing, but rather to just show the diff between more_logging_when_cannot_use_transaction and v0.25.0-crdb. Unfortuately that diff is highly polluted by 'auto-black-on-save' in my editor, but the real payload here is:

  • Give Connection a circular buffer holding the 20 most recent statements.
  • Append statements into that buffer in the coremost places I found. This took some real trial and error, given how PreparedStatments end up working and being heavily used by sqlalchemy. The append lines all mention "_recent_statements.append(".
  • When Transaction open() realizes the connection is already within a transaction, before we raise an exception, we structlog log an error including the id() of the connection plus all of its _recent_statements.

This is not for merge, only for us to read.

James Robinson added 3 commits July 28, 2022 13:31
…n the history of the connection use when we die of 'cannot use Connection.transaction() in a manually started transaction'
…n the history of the connection use when we die of 'cannot use Connection.transaction() in a manually started transaction'
@jlrobins jlrobins marked this pull request as draft July 28, 2022 23:16

async def __do_execute(self, executor):
protocol = self._connection._protocol
self._connection._recent_statements.append(self._query)
Copy link
Author

Choose a reason for hiding this comment

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

Remeber statements being executed by PreparedStatement objects.


con = self._connection

if con._top_xact is None:
if con._protocol.is_in_transaction():
logger.error(
Copy link
Author

Choose a reason for hiding this comment

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

Make structlog logging.error call with the connection's id and recent statements list before raising the transaction state-confused error.

@@ -113,11 +133,16 @@ def __init__(self, protocol, transport, loop,
else:
self._source_traceback = None

# circular buffer of most recent executed statements to assist in
Copy link
Author

Choose a reason for hiding this comment

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

New circular buffer of recent statements here in a connection.

@@ -518,6 +540,9 @@ def cursor(
Added the *record_class* parameter.
"""
self._check_open()

Copy link
Author

Choose a reason for hiding this comment

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

Record statements leading into a cursor factory. Unclear if sqla ends up using these.

@@ -311,7 +335,12 @@ async def execute(self, query: str, *args, timeout: float=None) -> str:
"""
self._check_open()

# Append to circular buffer of most recent executed statements
Copy link
Author

Choose a reason for hiding this comment

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

SQLA arg-free statements like BEGIN, COMMIT, etc. end up commit through execute() here and not through prepared statements.

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.

1 participant