您可以使用与mysqldb相同的连接执行多个原子提交吗

wgeznvg7  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(216)

我希望能够使用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()
lh80um4z

lh80um4z1#

不,mysql在一个会话中没有不同的事务“级别”。只有一个当前事务,提交或回滚会影响整个事务。
我想我们可以同时打开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会将一个排他索引锁带到索引的末尾,防止其他会话执行集群键中值较高的插入(第二个会话将阻塞,直到获得所需的锁;只有持有独占锁的会话通过回滚或提交来释放它,才会发生这种情况。)
锁问题适用于所有索引,而不仅仅是集群密钥。
连接池解决不了这个问题。
我指的独占锁是“间隙锁”。如果我们对同一个表进行插入,我们就必须绕过锁定,以避免在程序管理的会话持有这些锁时阻塞、等待锁。
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

相关问题