This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author zzzeek
Recipients erlendaasland, ghaering, james.oldfield, lemburg, maggyero, r.david.murray, zzzeek
Date 2021-01-05.18:58:08
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1609873088.98.0.489133104494.issue39457@roundup.psfhosted.org>
In-reply-to
Content
> Under your proposal, the first line would be changed to say "autocommit=True", even though not all the code below is in autocommit mode (according to the SQLite engine's definition). What's more, I could insert this line of code between statements 3 and 6:

  >  print("Autocommit mode?", conn.autocommit)

As Marc-Andre indicated, this is in fact how "autocommit" behaves on other drivers, including:

    psycopg2 - uses either connection.autocommit, or extensions.ISOLATION_LEVEL_AUTOCOMMIT
    pymysql - uses conn.autocommit(True|False)
    mysqldb - uses conn.autocommit(True|False)
    cx_Oracle - uses conn.autocommit
    pyodbc - uses conn.autocommit

With all of the above drivers, one can emit "BEGIN" and "COMMIT" using
connection.execute(), and within the scope of that BEGIN/COMMIT pair, the 
database "engine" itself is in a transaction.  The "driver" however remains in 
"autocommit" mode.   This mode specifically means the driver is not getting
involved in starting and stopping transactions. 

As Marc mentions, we're not supposed to be emitting "BEGIN" and "COMMIT" on 
the driver, but none of them get in the way of us doing so, and additionally
most databases support additional options for the "BEGIN/START TRANSACTION" phase
that aren't available in the DBAPIs so sometimes we don't have much choice at least for the "BEGIN" command.

Here's an example using psycopg2, where the timestamp now() will freeze
when we're in a transaction started using manual "BEGIN"/ "COMMIT", while .autocommit stays True, and otherwise match statement execution time if we're not:

    >>> import psycopg2
    >>> conn = psycopg2.connect(user="scott", password="tiger", host="localhost", database="test")
    >>> conn.autocommit = True
    >>> cursor = conn.cursor()
    >>> cursor.execute("SELECT 1")
    >>> cursor.execute("select now() = statement_timestamp()")
    >>> cursor.fetchall()
    [(True,)]
    >>> cursor.execute("BEGIN")
    >>> cursor.execute("select now() = statement_timestamp();")
    >>> cursor.fetchall()
    [(False,)]  # we're in a transaction
    >>> conn.autocommit   # still in driver-level autocommit
    True
    >>> cursor.execute("COMMIT")
    >>> cursor.execute("select now() = statement_timestamp();")
    >>> cursor.fetchall()
    [(True,)]

For SQLAlchemy we already support pysqlite's "isolation_level=None" to implement "autocommit" so this issue does not affect us much, but the meaning of the term "autocommit" at the driver level shouldn't be controversial at this point as there's a lot of precedent.   "connection.autocommit" does not refer to the current transactional state of the database, just the current preference set upon the driver itself.
History
Date User Action Args
2021-01-05 18:58:09zzzeeksetrecipients: + zzzeek, lemburg, ghaering, r.david.murray, maggyero, erlendaasland, james.oldfield
2021-01-05 18:58:08zzzeeksetmessageid: <1609873088.98.0.489133104494.issue39457@roundup.psfhosted.org>
2021-01-05 18:58:08zzzeeklinkissue39457 messages
2021-01-05 18:58:08zzzeekcreate