Вопрос

% sudo yum info MySQL-python.x86_64
Loaded plugins: priorities, update-motd, upgrade-helper
Installed Packages
Name        : MySQL-python
Arch        : x86_64
Version     : 1.2.3
Release     : 0.3.c1.1.9.amzn1

Shell #1:

% python
Python 2.6.9 (unknown, Oct 29 2013, 19:58:13)
[GCC 4.6.3 20120306 (Red Hat 4.6.3-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mysql.connector as mysqlconn
>>> cnx = mysqlconn.connect(...)
>>> cur = cnx.cursor()
>>> cur.execute("insert into sometable(id, name) values(%s, %s)", (28, "28"))
>>> cnx.commit()

Shell #2:

% python
Python 2.6.9 (unknown, Oct 29 2013, 19:58:13)
[GCC 4.6.3 20120306 (Red Hat 4.6.3-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mysql.connector as mysqlconn
>>> cnx = mysqlconn.connect(...)
>>> cur = cnx.cursor()
>>> cur.execute("select id, name from sometable where id = 28")
>>> cur.fetchall()
[(28, u'28')]

So far so good. Here's when things get surprising:

Shell #1:

>>> cur.close()
True
>>> cur = cnx.cursor()
>>> cur.execute("insert into sometable(id, name) values(%s, %s)", (29, "29"))
>>> cnx.commit()
>>>

Shell #2:

>>> cur.close()
True
>>> cur = cnx.cursor()
>>> cur.execute("select id, name from sometable where id = 29")
>>> cur.fetchall()
[]
>>>

For some reason, shell #2 with the current connection doesn't see the newly inserted record with id=29. Creating a new connection in shell #2 will fix the problem, but obviously I don't want to do that. I should note that /usr/bin/mysql has a consistent view at any time and sees the id=29 record when shell #2 doesn't, even when /usr/bin/mysql was opened long before doing anything in python. Also, shell #1 sees the id=29 record it just inserted with its current connection. So I suspect something wrong with the way I'm using connections with the python mysql connector, but I'm running out of ideas.

Это было полезно?

Решение

The default isolation level for MySQL is REPEATABLE READ. If you insert data in shell #1 and issue COMMIT, the data will be available only to newly started transactions after this COMMIT. The transaction in shell #2 was still ongoing and will not see the new data.

You can either change this by setting the default transaction isolation level on the server (or session), or, maybe better, set the isolation for the current transaction.

With MySQL Connector/Python v1.1, setting the isolation is easy using the MySQLConnection.start_transaction() method. In shell #2, do the following:

>>> cnx = mysql.connector.connect(...)
>>> cnx.start_transaction(isolation_level='READ COMMITTED')
>>> cur = cnx.cursor()
>>> cur.execute("select id, name from sometable where id = 29")
>>> cur.fetchall()
# Do something in shell #1 and commit there
>>> cur.execute("select id, name from sometable where id = 29")
>>> cur.fetchall()
[(28, u'28')]

The start_transaction is not PEP-249, but you can simply execute the SQL statement START TRANSACTION ISOLATION LEVEL READ COMMITTED or set the session variable tx_isolation. But I think the method start_transaction makes it easier.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top