Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在多线程中使用相同的db连接时,后面发生了什么?_Mysql_Multithreading_Python 3.x_Multiprocessing - Fatal编程技术网

Mysql 在多线程中使用相同的db连接时,后面发生了什么?

Mysql 在多线程中使用相同的db连接时,后面发生了什么?,mysql,multithreading,python-3.x,multiprocessing,Mysql,Multithreading,Python 3.x,Multiprocessing,在提出这个问题之前,我已经搜索了很多关于“跨线程共享相同的db连接”的内容。我得到的答案大多是否定的,而是使用连接池,但很少有人详细解释为什么我们不能这样做 然后,我使用多处理和多线程编写了一个示例代码,我正试图解决它,但仍然有一些困难需要解决。以下是我得到的: 多处理: 正如所料,此代码无法正常工作: ((None, None, 1, 'ttt', 'hhh', 1, 0, ''),) # process1 ((None, None, 2, 'zzz', '1256', 1, 0, '')

在提出这个问题之前,我已经搜索了很多关于“跨线程共享相同的db连接”的内容。我得到的答案大多是否定的,而是使用连接池,但很少有人详细解释为什么我们不能这样做

  • 然后,我使用多处理和多线程编写了一个示例代码,我正试图解决它,但仍然有一些困难需要解决。以下是我得到的:

    多处理:

    正如所料,此代码无法正常工作:

    ((None, None, 1, 'ttt', 'hhh', 1, 0, ''),)   # process1
    ((None, None, 2, 'zzz', '1256', 1, 0, ''),)  # process2  (1), this is normal output and should be what we want.
    

    并且跑了很多次,或者得到(1)或者(2)。原因(我认为)是: 虽然多处理并行运行,但process1的调用仍然早于process2。对于mysql,哪个进程的查询首先完成还不确定。如果process2提前完成,因为它们共享相同的连接,那么连接会按照调用的顺序返回数据,因此我得到了情况(2),否则得到了情况(1)。我说得对吗

    多线程

    最初我认为这段代码的结果将与多处理相同,但结果不同。它要么打印process1,要么打印process2,甚至在那里被卡住了。为什么?

  • 将db隔离级别更改为可序列化以解决此问题

    我试过了。对于多处理,它似乎是可行的;但对多线程没有影响。从理论上讲应该是可行的,不是吗?如果是这样的话,我无论如何也不会这么做,只是想办法解决它


  • 当python程序从多个线程内部使用单个
    conn
    对象时,它会在单个数据库连接上混合来自多个线程的消息流量(线程MySql)。那不行™.

    MySQL连接对象不是线程安全的。每个需要访问MySQL的线程都必须打开自己的连接。(MySQL连接池对象是线程安全的,因此每个线程都可以安全地请求、使用和释放池中的连接。)


    Pro提示:当复杂的长寿命软件(如
    pymysql
    )的开发人员告诉您它不是线程安全的时,请相信他们

    当python程序从多个线程内部使用单个
    conn
    对象时,它会在单个数据库连接上混合来自多个线程的消息流量(线程MySql)。那不行™.

    MySQL连接对象不是线程安全的。每个需要访问MySQL的线程都必须打开自己的连接。(MySQL连接池对象是线程安全的,因此每个线程都可以安全地请求、使用和释放池中的连接。)


    Pro提示:当复杂的长寿命软件(如
    pymysql
    )的开发人员告诉您它不是线程安全的时,请相信他们

    谢谢,如果说
    它在一个数据库连接上同时混合了来自多个线程的消息流量(线程MySql),这会更严格,不是吗?我还注意到Django中存在持久连接,但是Django如何将持久连接绑定到当前线程以防止其他线程使用它呢?谢谢,如果说
    它同时在一个数据库连接上混合来自多个线程的消息流量(线程MySql),这将更加严格,不是吗?我还注意到Django中存在持久连接,但是Django如何将持久连接绑定到当前线程以防止其他线程使用它呢?
    
    ((None, None, 1, 'ttt', 'hhh', 1, 0, ''),)   # process1
    ((None, None, 2, 'zzz', '1256', 1, 0, ''),)  # process2  (1), this is normal output and should be what we want.
    
    ((None, None, 2, 'zzz', '1256', 1, 0, ''),)
    ((None, None, 1, 'ttt', 'hhh', 1, 0, ''),)  # (2), this is incorrect output.
    
    import multiprocessing.dummy as multithread
    import pymysql
    from queue import Queue
    
    conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='123456', db='test')
    
    def operate(sql):
        cur = conn.cursor()
        cur.execute(sql)
        cur.close()
        res.put(cur.fetchall())
    
    pool = multithread.Pool(4)
    res = Queue()
    
    for seq in range(1, 3):
        sql = "SELECT * FROM `user` WHERE `id` = %d" % seq
        p = pool.apply_async(operate, [sql, ])
    
    pool.close()
    pool.join()
    
    conn.close()
    print(res.get())