engrave. 2023-02-16 20:22 采纳率: 71.4%
浏览 69
已结题

python,django,多线程,事务

问题:如何操作使多线程达到普通方法调用的效果,使一次子线程失败,所有子线程及主线程保持一致,不去操作数据库

img


    @action(methods=['post'], detail=False)
    @transaction.atomic
    def uploadTest(self, request):
        data = {'code': 0, 'msg': '', 'data': []}
        connection.cursor().execute("INSERT INTO bby_test (id, name,age) VALUES (%s, %s, %s)", (1, 'name', 1))
        for i in range(0, 5):
            # 1.多线程调用 X
             pool.submit(Test,i)
            # 2.方法调用 √
             Test(i)
            # 问题:如何操作使多线程达到普通方法调用的效果,使一次子线程失败,所有子线程及主线程保持一致,不去操作数据库
        return JsonResponse(data)
 
def Test(i):
    print(i)
    if i % 2 == 0:
        a = 1/0
    connection.cursor().execute("INSERT INTO bby_test (id, name,age) VALUES (%s, %s, %s)", (2, 'name2', 2))
 
  • 写回答

6条回答 默认 最新

  • 社区专家-Monster-XH 2023-02-16 20:38
    关注

    基于Monster 组和GPT的调写:
    要让多线程达到普通方法调用的效果,使一次子线程失败,所有子线程及主线程保持一致,可以使用以下步骤:

    import threading
    
    lock = threading.Lock()  # 创建线程锁
    
    @action(methods=['post'], detail=False)
    def uploadTest(self, request):
        data = {'code': 0, 'msg': '', 'data': []}
        connection.cursor().execute("INSERT INTO bby_test (id, name,age) VALUES (%s, %s, %s)", (1, 'name', 1))
        threads = []
        for i in range(0, 5):
            t = threading.Thread(target=Test, args=(i,))
            threads.append(t)
            t.start()
    
        # 等待所有子线程结束
        for t in threads:
            t.join()
    
        return JsonResponse(data)
    
    def Test(i):
        try:
            print(i)
            if i % 2 == 0:
                raise Exception("Exception in thread {}".format(i))
            with lock:
                # 线程锁保证多个线程不会同时修改数据库
                connection.cursor().execute("INSERT INTO bby_test (id, name,age) VALUES (%s, %s, %s)", (2, 'name2', 2))
        except Exception as e:
            # 异常捕获,保证子线程和主线程都能处理异常
            with lock:
                print(e)
    
    
    

    在这个例子中,我们使用ThreadPoolExecutor创建一个具有最大工作线程数为5的线程池。然后,我们将上传数据的任务添加到线程池中,使用as_completed方法迭代所有线程,并捕获可能抛出的异常。如果有任何一个线程抛出异常,则向所有线程发送一个停止信号。当所有线程完成时,我们检查是否有任何线程抛出了异常。如果有,则将异常重新抛出,以便在主线程中处理。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 2月25日
  • 已采纳回答 2月17日
  • 创建了问题 2月16日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改