我希望能够使用 Python3 中的 MySQLDb 库使用相同的连接对象来执行原子提交。我认为不必为了执行多个原子提交而建立与数据库的两个网络连接,但情况似乎就是这样。是创建连接池的唯一替代方法吗?
例如,我希望能够做这样的事情
conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")
try:
cur = conn.cursor()
cur.execute("insert into my_table values (1, 2, 3)")
cur.execute("insert into my_table values (4, 5, 6)")
cur1 = conn.cursor()
cur1.execute("insert into my_table values (12, 22, 32)")
cur1.execute("insert into my_table values (42, 52, 62)")
# Commit the last 2 inserts first
# This won't work because cursor.commit() doesn't exist
cur1.commit()
# Now commit the first two inserts
cur.commit() # Again, this won't work
except FailedTransaction as ex:
# Rollback the actual transaction that failed.
# Cursor aren't transactions, but there is no transaction
# object so this is the best I can come up with.
ex.cursor.rollback()
conn.close()
最佳答案
不,MySQL 在 session 中没有不同的事务“级别”。当前只有一个事务,COMMIT 或 ROLLBACK 会影响整个事务。
<小时/>我认为我们可以同时打开两个到 MySQL 的连接。这不需要连接池。 (出于其他原因,连接池会是一个很好的选择)。
conn1 = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")
conn2 = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")
如果我们有两个连接,那么我们应该能够在每个连接上独立运行事务 。 但这可能不适用于您的用例。假设InnoDB,如果在第一个连接上插入的行是簇键中的“最高”值,则InnoDB会对索引末尾采取独占索引锁,以防止其他 session 执行簇键中更高值的插入。 (第二个 session 将阻塞,直到获得所需的锁;并且只有持有独占锁的 session 通过 ROLLBACK 或 COMMIT 释放它时才会发生这种情况。)
并且锁定问题适用于所有索引,而不仅仅是集群键。
连接池并不能解决这个问题。
<小时/>我指的独占锁是“间隙锁”。如果我们要对同一个表进行插入,那么当这些锁由我们的程序管理的 session 持有时,我们必须解决锁定问题,以避免阻塞、等待锁。
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_gap_lock
https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html
关于mysql - 您可以使用 MySQLdb 的同一连接执行多个原子提交吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50206523/