2017-06-27 108 views
0

我有一個關於MySQL和事務的問題。我與MySQL 5.7.18,蟒蛇3和Oracle的MySQL連接器v2.1.4事務回滾和不提交有什麼區別(在MySQL中)?

工作,我不明白 a)具有交易和錯誤的情況下,-in之間的區別 - 回滾和 B)不具有交易和 - 如果有錯誤 - 只是不提交更改。

兩者似乎都給我帶來完全相同的結果(即表中沒有條目,請參閱下面的代碼示例)。這與使用InnoDB有關嗎?否則結果會有所不同?

什麼是使用事務,如果 1)我不能回滾COMMITED變化和 2)我可能只是以及不更改提交(直到我與我的任務或確認某些查詢沒有提出做的好處任何例外)?

我試圖找到你在https://downloads.mysql.com/docs/connector-python-en.a4.pdf這些問題,但未能找到本質的區別。

有人問幾乎相同的問題,並收到一些答覆,但我不認爲這些答案實際上包含答案:Mysql transaction : commit and rollback回覆集中在打開多個連接和更改的可見性。這就是它的全部嗎?

import mysql.connector 

# Connect to MySQL-Server 
conn = mysql.connector.connect(user='test', password='blub', 
           host='127.0.0.1', db='my_test') 
cursor = conn.cursor(buffered=True) 

# This is anyway the default in mysql.connector 
# cursor.autocommit = False 

sql = """CREATE TABLE IF NOT EXISTS `my_test`.`employees` (
    `emp_no` int(11) NOT NULL AUTO_INCREMENT, 
    `first_name` varchar(14) NOT NULL, 
    PRIMARY KEY (`emp_no`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8""" 
try: 
    cursor.execute(sql) 
    conn.commit() 
except: 
    print("error") 

# Arguments on default values 
# conn.start_transaction(consistent_snapshot=False, 
#   isolation_level=None, readonly=False) 

sql = """INSERT INTO `my_test`.`employees` 
(`first_name`) 
VALUES 
(%s);""" 

employees = {} 
employees["1"] = ["Peter"] 
employees["2"] = ["Bruce"] 
for employee, value in employees.items(): 
    cursor.execute(sql, (value[0],)) 
    print(conn.in_transaction) 

# If I do not commit the changes, table is left empty (whether I write 
# start_transaction or not) 
# If I rollback the changes (without commit first), table is left empty 
# (whether I write start_transaction or not) 
# If I commit and then rollback, the rollback had no effect (i.e. there are 
# values in the table (whether I write start_transaction or not) 
conn.commit() 
conn.rollback() 

非常感謝您的幫助!我很感激。

回答

0

我認爲有沒有承諾,也不回滾葉處於運行狀態的交易,其中可能仍持有像鎖等資源

0

你的決定有一個事務應該考慮到有一個衆多原因包括具有多個語句,每個語句都提交寫入數據庫。

在你的榜樣,我不認爲它的確與衆不同,但在更復雜的情況,你需要一個事務,以確保ACID。

0

那麼它並不重要的數據庫使用的是,當你調用一個事務,如果我寫了一個事務插入的東西,將鎖定資源(即任何表),直到交易完成或回滾例如一個表測試測試表將被鎖定,直到事務完成,這可能會導致死鎖,因爲其他人可能需要該表...你可以嘗試一下,你只需在第一個實例運行事務中打開你的mysql的兩個實例,而不需要提交在第二次嘗試插入同一個表的東西......它會清除你懷疑你的查詢運行時

0

事務阻止其他查詢修改該數據。此外,事務範圍可以包含多個查詢 - 因此,如果發生錯誤,您可以回滾所有這些查詢,但如果其中一些成功運行並且只有一個查詢導致錯誤,那麼情況並非如此,在這種情況下,您可能會結束與JLH說的一樣,部分承諾的結果。

+0

謝謝您的回覆。我想我不得不不同意 - 這就是我的困惑中的一部分。事務應該將語句「捆綁」成原子。因此,如果我必須運行3個順序語句(例如INSERT INTO)並且第二個語句失敗,那麼我不希望我的表/ DB(** all或nothing **)發生任何更改。 **但是**:如果我只是運行三條語句 而不聲明它們是一個事務並且只有在所有三條語句都成功完成時才提交,那麼情況就是如此。 –

+1

請參閱上面的代碼。有兩個數據更改語句(cursor.execute)。 這兩個都適用,當且僅當我承諾。無論我是否明確寫入 start_transaction。如果我檢查異常/錯誤,並且第二條語句引發異常,我可以不提交。沒有數據會被寫入表格。雖然我不會(明確地?)將這些陳述作爲一個交易捆綁在一起,但它們是「完全」原子的。 也許我的困惑來自默認情況下在MySQL中自動提交,而默認情況下,在mysql.connector中爲python默認爲_off_。 –

+0

Ahhh - 良好的反饋意見 - 我不知道是不是這樣!一旦發現,請更新評論。關於捆綁 - 交易是一種很好的做法,因爲它是顯式的,並且不依賴於其他變量(如默認設置,語句數量等) - 儘管在這個簡單示例中它可能並不重要,但它可能在更復雜場景! –

相關問題