事务回滚和未提交之间有什么区别(在MySQL中)?

时间:2017-06-27 10:13:25

标签: python mysql sql python-3.x transactions

我对MySQL和交易有疑问。我使用MySQL 5.7.18,python 3和Oracle mysql连接器v2.1.4

我不明白它们之间的区别 a)有一个事务和 - 如果出现错误 - 回滚和 b)没有交易,并且 - 如果出现错误 - 根本没有提交更改。

两者似乎都给我留下了完全相同的结果(即表中没有条目,请参阅下面的代码示例)。这是否与使用InnoDB有关 - 否则结果会有所不同?

如果使用交易有什么好处 1)我无法回滚提交的更改和 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()

非常感谢您的帮助!我很感激。

4 个答案:

答案 0 :(得分:0)

我认为没有提交或回滚会使事务处于运行状态,在该状态下它仍然可以保存锁等资源

答案 1 :(得分:0)

您决定进行交易时应考虑到拥有交易的众多原因,包括拥有多个提交写入数据库的多个语句。

在您的示例中,我认为它不会有所作为,但在更复杂的情况下,您需要一个事务来确保ACID。

答案 2 :(得分:0)

当你调用一个事务时,你使用哪个数据库并不重要,它会锁定资源(即任何表)直到事务完成或回滚,例如,如果我写一个事务来插入一些东西到一个事务表测试测试表将被锁定,直到事务完成,这可能导致死锁,因为其他人可能需要该表...你可以尝试自己只需在第一个实例运行事务中打开你的mysql的两个实例而不提交第二次尝试在同一张桌子上插入一些东西......这将清除你的怀疑

答案 3 :(得分:0)

事务阻止其他查询在您的查询运行时修改数据。此外,事务范围可以包含多个查询 - 因此您可以在发生错误时回滚所有查询,而如果其中一些查询成功运行并且只有一个查询导致错误,则不是这种情况,在这种情况下您可能会结束像JLH所说,部分承诺的结果。