我正面临着多个线程试图将数据插入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的数据没有重叠,因此我们不必担心重复密钥问题。
经过实验,似乎有些线程会挂起并且没有响应。
答案 0 :(得分:1)
根据MySQL Connector/Python Developer Guide,mysql.connector.threadsafety
属性为1
。
根据PEP 249,threadsafety
属性的含义如下:
0-线程可能无法共享模块。
1-线程可以共享模块,但不能共享连接。
2-线程可以共享模块和连接。
3-线程可以共享模块,连接和游标。
在以上上下文中共享意味着两个线程可以使用资源,而无需使用互斥量信号量将其包装以实现资源锁定。请注意,您无法始终通过使用互斥锁管理访问来确保外部资源线程安全:该资源可能依赖于全局变量或您无法控制的其他外部源。
在您的示例中,您的线程共享一个连接。没有任何明确的资源锁定。这很可能导致线程问题,并且您观察到的症状(线程锁定)并非意外。
此示例中的简单解决方案是为每个线程提供自己的连接对象。
(如果线程数很大,建议您使用一个并发连接数受限制的连接池。DB服务器将限制一个客户端可以打开的连接数。服务器端资源。此外,在某个时候,您正在使用所有特定的服务器端资源;例如,CPU,内存,磁盘带宽,网络带宽,除此之外,添加更多客户端线程不会增加吞吐量。 )