2017-06-27 61 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 - 良好的反馈意见 - 我不知道是不是这样!一旦发现,请更新评论。关于捆绑 - 交易是一种很好的做法,因为它是显式的,并且不依赖于其他变量(如默认设置,语句数量等) - 尽管在这个简单示例中它可能并不重要,但它可能在更复杂场景! –

相关问题