Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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
Java 将数据库记录集流式传输到多个线程工作线程_Java_Database_Multithreading_Recordset_Dispatch - Fatal编程技术网

Java 将数据库记录集流式传输到多个线程工作线程

Java 将数据库记录集流式传输到多个线程工作线程,java,database,multithreading,recordset,dispatch,Java,Database,Multithreading,Recordset,Dispatch,我有一个流程,需要从数据库中流式传输数据,并将记录传递到外部服务器进行处理,然后返回结果存储回数据库 Get database row from table A Hand off to external server Receive result insert database row into table B 目前这是一个单线程操作,瓶颈是外部服务器进程,因此我想通过使用外部服务器进程的其他实例来处理请求来提高性能 Get 100 database rows from table A

我有一个流程,需要从数据库中流式传输数据,并将记录传递到外部服务器进行处理,然后返回结果存储回数据库

Get database row from table A
Hand off to external server
Receive result
insert database row into table B
目前这是一个单线程操作,瓶颈是外部服务器进程,因此我想通过使用外部服务器进程的其他实例来处理请求来提高性能

Get 100 database rows from table A   
  For each row
    Hand off to external server 1
    Receive Result
    insert database row into table B 
In parallel get 100 database rows from table A
  For each row
    Hand off to external server 2
    Receive Result
    insert database row into table B
问题1 我一直在研究Java线程池,并以这种方式将记录发送到外部服务器,但是我不确定如何在工作人员不拒绝新任务的情况下尽快从数据库中获取记录。这可以通过线程池实现吗?应该使用什么体系结构来实现这一点

问题2 目前,我已经通过使用批处理语句优化了数据库插入,并且只在处理了2000条记录后执行一次。是否有可能在工人内部采用类似的方法


我们将非常感谢您对这个问题的解决方案提供的任何帮助

根据您的评论,我认为关键在于控制待定任务的数量。您有几个选择:

  • 对数据集中的记录数进行估计。然后,确定能够产生合理数量任务的批量大小。例如,如果要将挂起的任务计数限制为100。然后,如果您有100K条记录,那么您可以拥有1K的批大小。如果您有1Mil记录,则将批量大小设置为10K

  • 向线程池提供您自己的有界BlockingQueue。如果您以前没有这样做过,那么在进行此操作之前,您可能应该仔细研究
    java.util.concurrent

  • 或者您可以使用
    java.util.concurrent.Semaphore
    ,它比用户提供的队列更简单:

    • 声明具有挂起任务计数限制的信号量
    Semaphore mySemaphore=新信号量(最大挂起任务计数)

    • 由于任务生成速度很快,因此可以使用单个线程生成所有任务。在任务生成线程中:

  • 请您解释一下“我不知道如何在没有工人拒绝新任务的情况下尽快从数据库中获取记录。”?线程池是否会拒绝您的任务,因为您生成的任务太多,以至于线程池的等待队列已满?如果是这样,您可以使每个任务的批处理大小更大。(例如,1000行而不是100行)我可以增加队列的大小,但鉴于我将有固定数量的工人,我可能会达到队列仍然充满的情况。我能想到的解决这个问题的唯一方法是调整程序,将新任务的创建暂停n毫秒,此时工人应该已经完成了足够的队列。
    
        while(hasMoreTasks()) {
            // this will block if you've reached the count limit
            mySemaphore.acquire(); 
            // generate a new task only after acquire
            // The new task must have a reference to the Semaphore
            Task task = new Task(..., mySemaphore);
            threadpool.submit(task);
        }
        // now that you've generated all tasks,
        // time to wait for them to finish. 
        // you may have a better way to detect that, however
        while(mySemaphore.availablePermits() < max_pending_task_count) {
            Thread.sleep(some_time);
        }
        // now, go ahead dealing with the results
    
        
        public void run() {
            ...
            // when finished, do a release which increases the permit 
            // by 1 and inform your task generator thread to produce 1 more task
            mySemaphore.release();
        }