% 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')]
到目前为止一切顺利。事情变得令人惊讶:
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()
[]
>>>
由于某种原因,具有当前连接的shell#2看不到id = 29的新插入记录。在shell#2中创建一个新连接将解决问题,但显然我不想这样做。我应该注意/ usr / bin / mysql在任何时候都有一致的视图,并且当shell#2没有时会看到id = 29的记录,即使在python中做任何事情之前很久就打开了/ usr / bin / mysql。另外,shell#1看到它刚插入的id = 29记录及其当前连接。所以我怀疑我使用python mysql连接器的连接方式有问题,但我的想法已经用完了。
答案 0 :(得分:2)
MySQL的默认隔离级别为REPEATABLE READ。如果在shell#1中插入数据并发出COMMIT,则此COMMIT之后的数据仅可用于新启动的事务。 shell#2中的事务仍在进行中,不会看到新数据。
您可以通过在服务器(或会话)上设置默认事务隔离级别来更改此设置,或者更好的是,为当前事务设置隔离。
使用MySQL Connector / Python v1.1,使用MySQLConnection.start_transaction()
method可以轻松设置隔离。在shell#2中,执行以下操作:
>>> 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')]
start_transaction
不是PEP-249,但您可以只执行SQL语句START TRANSACTION ISOLATION LEVEL READ COMMITTED
或设置会话变量tx_isolation
。但我认为方法start_transaction
使其更容易。