2014-02-23 59 views
1
% 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 

殼牌#1:MySQL的連接器未示出插入結果

% 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() 

殼牌#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')] 

到目前爲止好。

殼牌#1:

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

殼牌#2:當事情變得奇怪這裏的

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

出於某種原因,殼牌#2與當前連接沒有看到新插入的記錄ID = 29。在shell#2中創建一個新的連接將解決這個問題,但顯然我不想那樣做。我應該注意到/ usr/bin/mysql在任何時候都有一個一致的視圖,當shell#2沒有時,即使在/ usr/bin/mysql在python中執行任何操作之前打開它,也會看到id = 29的記錄。另外,shell#1可以看到它剛插入的當前連接的id = 29記錄。所以我懷疑我使用python mysql連接器的連接方式有問題,但我沒有想法。

+0

這很有趣:在發送我的SELECT語句之前,在shell#2(它只能從db讀取數據,從不寫入數據)中添加一個cnx.commit()以修復問題。我錯過了什麼嗎?我真的不想設置autocommit = True,在所有的SELECT語句之前都不發送COMMIT。 – user3344275

+0

我應該添加:ENGINE = InnoDB – user3344275

+0

添加更多:/ usr/bin/mysql會看到新記錄,因爲它有autocommit = 1。禁用它(設置autocommit = 0)後,它也看不到新行。我懷疑默認的隔離級別是問題:http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html – user3344275

回答

2

MySQL的默認隔離級別是REPEATABLE READ。如果您在shell#1中插入數據併發出COMMIT,那麼在此COMMIT之後,數據僅可用於新開始的事務。 shell#2中的事務仍在繼續,不會看到新的數據。

您可以通過在服務器(或會話)上設置默認事務隔離級別來更改此設置,或者可以更好地設置當前事務的隔離級別。

使用MySQL連接器/ Python v1.1,使用MySQLConnection.start_transaction() method可以輕鬆設置隔離。在外殼#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使它更容易。