From: Daniel Fortunov Date: Sat, 25 Jul 2020 11:36:47 +0000 (+0100) Subject: connection: Move lock acquisition out of _exec_commit_rollback() X-Git-Tag: 3.0.dev0~450 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a85dfe98ff1c55448dd84a251f7d779c77b26913;p=thirdparty%2Fpsycopg.git connection: Move lock acquisition out of _exec_commit_rollback() --- diff --git a/psycopg3/psycopg3/connection.py b/psycopg3/psycopg3/connection.py index 71d564ef6..67f9df4c1 100644 --- a/psycopg3/psycopg3/connection.py +++ b/psycopg3/psycopg3/connection.py @@ -265,24 +265,26 @@ class Connection(BaseConnection): ) def commit(self) -> None: - self._exec_commit_rollback(b"commit") + with self.lock: + self._exec_commit_rollback(b"commit") def rollback(self) -> None: - self._exec_commit_rollback(b"rollback") + with self.lock: + self._exec_commit_rollback(b"rollback") def _exec_commit_rollback(self, command: bytes) -> None: - with self.lock: - status = self.pgconn.transaction_status - if status == TransactionStatus.IDLE: - return - - self.pgconn.send_query(command) - (pgres,) = self.wait(execute(self.pgconn)) - if pgres.status != ExecStatus.COMMAND_OK: - raise e.OperationalError( - f"error on {command.decode('utf8')}:" - f" {pq.error_message(pgres, encoding=self.codec.name)}" - ) + # Caller must hold self.lock + status = self.pgconn.transaction_status + if status == TransactionStatus.IDLE: + return + + self.pgconn.send_query(command) + (pgres,) = self.wait(execute(self.pgconn)) + if pgres.status != ExecStatus.COMMAND_OK: + raise e.OperationalError( + f"error on {command.decode('utf8')}:" + f" {pq.error_message(pgres, encoding=self.codec.name)}" + ) @classmethod def wait( @@ -377,24 +379,26 @@ class AsyncConnection(BaseConnection): ) async def commit(self) -> None: - await self._exec_commit_rollback(b"commit") + async with self.lock: + await self._exec_commit_rollback(b"commit") async def rollback(self) -> None: - await self._exec_commit_rollback(b"rollback") + async with self.lock: + await self._exec_commit_rollback(b"rollback") async def _exec_commit_rollback(self, command: bytes) -> None: - async with self.lock: - status = self.pgconn.transaction_status - if status == TransactionStatus.IDLE: - return - - self.pgconn.send_query(command) - (pgres,) = await self.wait(execute(self.pgconn)) - if pgres.status != ExecStatus.COMMAND_OK: - raise e.OperationalError( - f"error on {command.decode('utf8')}:" - f" {pq.error_message(pgres, encoding=self.codec.name)}" - ) + # Caller must hold self.lock + status = self.pgconn.transaction_status + if status == TransactionStatus.IDLE: + return + + self.pgconn.send_query(command) + (pgres,) = await self.wait(execute(self.pgconn)) + if pgres.status != ExecStatus.COMMAND_OK: + raise e.OperationalError( + f"error on {command.decode('utf8')}:" + f" {pq.error_message(pgres, encoding=self.codec.name)}" + ) @classmethod async def wait(cls, gen: proto.PQGen[proto.RV]) -> proto.RV: