Skip to content

Commit 3446516

Browse files
author
Erlend Egeberg Aasland
authored
bpo-44042: Optimize sqlite3 begin transaction (GH-25908)
1 parent 5c2191d commit 3446516

File tree

3 files changed

+38
-46
lines changed

3 files changed

+38
-46
lines changed

Modules/_sqlite/connection.c

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -405,42 +405,6 @@ int pysqlite_check_connection(pysqlite_Connection* con)
405405
}
406406
}
407407

408-
PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
409-
{
410-
int rc;
411-
sqlite3_stmt* statement;
412-
413-
Py_BEGIN_ALLOW_THREADS
414-
rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement,
415-
NULL);
416-
Py_END_ALLOW_THREADS
417-
418-
if (rc != SQLITE_OK) {
419-
_pysqlite_seterror(self->db);
420-
goto error;
421-
}
422-
423-
rc = pysqlite_step(statement, self);
424-
if (rc != SQLITE_DONE) {
425-
_pysqlite_seterror(self->db);
426-
}
427-
428-
Py_BEGIN_ALLOW_THREADS
429-
rc = sqlite3_finalize(statement);
430-
Py_END_ALLOW_THREADS
431-
432-
if (rc != SQLITE_OK && !PyErr_Occurred()) {
433-
_pysqlite_seterror(self->db);
434-
}
435-
436-
error:
437-
if (PyErr_Occurred()) {
438-
return NULL;
439-
} else {
440-
Py_RETURN_NONE;
441-
}
442-
}
443-
444408
/*[clinic input]
445409
_sqlite3.Connection.commit as pysqlite_connection_commit
446410

Modules/_sqlite/connection.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ typedef struct
107107

108108
extern PyTypeObject *pysqlite_ConnectionType;
109109

110-
PyObject* _pysqlite_connection_begin(pysqlite_Connection* self);
111-
112110
int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor);
113111
int pysqlite_check_thread(pysqlite_Connection* self);
114112
int pysqlite_check_connection(pysqlite_Connection* con);

Modules/_sqlite/cursor.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,38 @@ static int check_cursor(pysqlite_Cursor* cur)
415415
return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
416416
}
417417

418+
static int
419+
begin_transaction(pysqlite_Connection *self)
420+
{
421+
int rc;
422+
sqlite3_stmt *statement;
423+
424+
Py_BEGIN_ALLOW_THREADS
425+
rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement,
426+
NULL);
427+
Py_END_ALLOW_THREADS
428+
429+
if (rc != SQLITE_OK) {
430+
_pysqlite_seterror(self->db);
431+
goto error;
432+
}
433+
434+
Py_BEGIN_ALLOW_THREADS
435+
sqlite3_step(statement);
436+
rc = sqlite3_finalize(statement);
437+
Py_END_ALLOW_THREADS
438+
439+
if (rc != SQLITE_OK && !PyErr_Occurred()) {
440+
_pysqlite_seterror(self->db);
441+
}
442+
443+
error:
444+
if (PyErr_Occurred()) {
445+
return -1;
446+
}
447+
return 0;
448+
}
449+
418450
static PyObject *
419451
get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation)
420452
{
@@ -431,7 +463,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
431463
PyObject* parameters = NULL;
432464
int i;
433465
int rc;
434-
PyObject* result;
435466
int numcols;
436467
PyObject* column_name;
437468
sqlite_int64 lastrowid;
@@ -515,13 +546,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
515546

516547
/* We start a transaction implicitly before a DML statement.
517548
SELECT is the only exception. See #9924. */
518-
if (self->connection->begin_statement && self->statement->is_dml) {
519-
if (sqlite3_get_autocommit(self->connection->db)) {
520-
result = _pysqlite_connection_begin(self->connection);
521-
if (!result) {
522-
goto error;
523-
}
524-
Py_DECREF(result);
549+
if (self->connection->begin_statement
550+
&& self->statement->is_dml
551+
&& sqlite3_get_autocommit(self->connection->db))
552+
{
553+
if (begin_transaction(self->connection) < 0) {
554+
goto error;
525555
}
526556
}
527557

0 commit comments

Comments
 (0)