当多个线程正在写入mysql中的单个表时会发生什么?

时间:2019-06-18 08:24:38

标签: python mysql multithreading

我正面临着多个线程试图将数据插入mysql中同一表的情况,**不用显式处理就可以吗? **恐怕每个线程都在插入,某些线程将被锁定并保持太长时间,然后导致程序损坏。

基本上我想做的是以下事情:

import threading
import mysql.connector

db = mysql.connector.connect()
cursor = db.cursor()


def update_to_table(data):
    sql = "insert into my_db.my_table values(%s)" % data
    cursor.excute(sql)
    db.commit()
    print("update complete!")


for i in range(10):
    print("%d -th time..." % i)
    data = get_data(i)
    t = threading.Thread(target=update_to_table, args=(data,))
    t.start()

我是否需要检查是否正在插入其他线程,并保持并等待它们完成等...

不同i的数据没有重叠,因此我们不必担心重复密钥问题。

经过实验,似乎有些线程会挂起并且没有响应。

1 个答案:

答案 0 :(得分:1)

根据MySQL Connector/Python Developer Guidemysql.connector.threadsafety属性为1

根据PEP 249threadsafety属性的含义如下:

  

0-线程可能无法共享模块。

     

1-线程可以共享模块,但不能共享连接。

     

2-线程可以共享模块和连接。

     

3-线程可以共享模块,连接和游标。

     

在以上上下文中共享意味着两个线程可以使用资源,而无需使用互斥量信号量将其包装以实现资源锁定。请注意,您无法始终通过使用互斥锁管理访问来确保外部资源线程安全:该资源可能依赖于全局变量或您无法控制的其他外部源。

在您的示例中,您的线程共享一个连接。没有任何明确的资源锁定。这很可能导致线程问题,并且您观察到的症状(线程锁定)并非意外。

此示例中的简单解决方案是为每个线程提供自己的连接对象。

(如果线程数很大,建议您使用一个并发连接数受限制的连接池。DB服务器将限制一个客户端可以打开的连接数。服务器端资源。此外,在某个时候,您正在使用所有特定的服务器端资源;例如,CPU,内存,磁盘带宽,网络带宽,除此之外,添加更多客户端线程不会增加吞吐量。 )