2012-08-12 27 views
3

我在python中使用mysqldb。MySQL並鎖定表,讀取,然後截斷

我需要爲表格執行以下操作。

1) Lock 
2) Read 
3) Truncate the table 
4) Unlock 

當我運行下面的代碼時,我得到了下面的錯誤。所以,我不確定如何鎖定表格以便讀取它,然後截斷表格。我需要確保沒有其他連接讀取數據。

asin_list = [] 
    conn = MySQLdb.connect(host=parms['database']['operations']['host'],user=parms['database']['operations']['username'],passwd=parms['database']['operations']['password'],db=parms['database']['operations']['database']) 
    cursor = conn.cursor() 

    query = "LOCK TABLES asin_one_time_only READ" 
    cursor.execute(query) 
    print 'fu1' 

    query = """select asin FROM asin_one_time_only""" 
    cursor.execute(query) 
    rows = cursor.fetchall() 
    for row in rows: 
     asin_list.append(row[0]) 

    print asin_list 
    print 'fu2' 
    query = "UNLOCK TABLES;" 
    cursor.execute(query) 
    conn.commit() 


    print 'fu3' 
    query = "LOCK TABLES asin_one_time_only WRITE" 
    cursor.execute(query) 


    query = """truncate table amz_one_time_only""" 
    cursor.execute(query) 
    conn.commit() 

    print 'fu3' 
    query = "UNLOCK TABLES;" 
    cursor.execute(query) 
    conn.commit() 

    cursor.close() 
    conn.close() 

Traceback (most recent call last): 
    File "/home/ubuntu/workspace/Amazon-Products-Crawler-1/threaded_crawl.py", line 1086, in <module> 
    onetime = getOneTimeOnlyAsins(parms) 
    File "/home/ubuntu/workspace/Amazon-Products-Crawler-1/threaded_crawl.py", line 109, in getOneTimeOnlyAsins 
    cursor.execute(query) 
    File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 166, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/lib/pymodules/python2.7/MySQLdb/connections.py", line 35, in defaulterrorhandler 
    raise errorclass, errorvalue 
_mysql_exceptions.OperationalError: (1192, "Can't execute the given command because you have active locked tables or an active transaction") 

回答

8

您不能截斷爲寫入而鎖定的表。這是因爲「截斷」意思是「銷燬表格,並用相同的模式重新創建一個新表格。」

然而你可以,表中。而不是TRUNCATE TABLE asin_one_time_only使用DELETE FROM asin_one_time_only。請注意,這不會重置自動增量編號。如果你想重置爲好,使用ALTER TABLE asin_one_time_only auto_increment=1

我建議這樣做:

LOCK TABLES asin_one_time_only READ; 
SELECT asin FROM asin_one_time_only; 
-- minimize the possibility of someone writing to the table in-between 
-- an "UNLOCK TABLES" and a "LOCK TABLES" by just issuing a new LOCK TABLES 
-- I am not 100% sure that MySQL will do this atomically, so there is a 
-- possibility that you may delete a row that was not read. 
-- If this is unacceptable, then use a "LOCK TABLES asin_one_time_only WRITE" 
-- from the very beginning. 
LOCK TABLES asin_one_time_only WRITE; 
DELETE FROM asin_one_time_only; 
ALTER TABLE asin_one_time_only auto_increment=1; 
UNLOCK TABLES; 
+0

我這個錯誤是我刪除FROM表而不是trncate。 amz_one_time_only'未鎖定LOCK TABLES – Tampa 2012-08-12 10:25:45

+0

您的表是amz_one_time_only還是asin_one_time_only? – 2012-08-12 10:27:45

+0

哎呦..我不好。有用。謝謝 – Tampa 2012-08-12 10:36:17

1

您不能截斷爲寫入而鎖定的表。

有一個在這裏的問題一整個辯論:http://bugs.mysql.com/bug.php?id=20667

你能做什麼,不過是刪除該表並重新創建它。

+1

如果你刪除表,鎖將被釋放。這意味着正在讀取/寫入表格的其他客戶端在刪除表格和重新創建表格之間的瞬間會得到「表格不存在」錯誤而不是阻塞。如果這是不可接受的,那麼你需要清空表格,而不是刪除它。 – 2012-08-12 10:26:07