关于在jdbc中使用multithreading的教程

我们公司有一个每天运行的批处理应用程序,它主要做一些数据库相关的工作,例如从文件导入数据到数据库表。

该应用程序中定义了20多个任务,每个任务可能依赖于其他任务。 应用程序逐个执行任务,整个应用程序在单个线程中运行。

完成所有任务需要3~7个小时。 我认为它太长了,所以我想也许我可以通过multithreading提高性能。

我认为由于任务之间存在依赖关系,因此并行运行任务并不好(或者说并不容易),但也许我可以使用multithreading来提高任务内部的性能。

例如:我们有一个定义为“ImportBizData”的任务,它将数据从数据文件复制到数据库表中(通常包含100,0000多行)。 我想知道是否值得使用multithreading?

正如我对multithreading知之甚少,我希望有人提供一些关于这个主题的教程链接。

multithreading将提高您的性能,但您需要了解以下几点:

  1. 每个线程都需要自己的JDBC连接。 线程之间不能共享连接,因为每个连接也是一个事务。
  2. 以块的forms上传数据并commit一次,以避免累积大量的回滚/撤消表。
  3. 将任务分成几个工作单位,每个单位完成一项工作。

详细说明最后一点:目前,您有一个任务可以读取文件,解析它,打开JDBC连接,进行一些计算,将数据发送到数据库等。

你应该做什么:

  1. 一个(!)线程来读取文件并从中创建“作业”。 每份工作都应该包含一个小而不是太小的“工作单元”。 将它们推入队列
  2. 下一个线程等待队列中的作业并进行计算。 当步骤#1中的线程等待慢速硬盘返回新的数据行时,可能会发生这种情况。 此转换步骤的结果将进入下一个队列
  3. 一个或多个通过JDBC上传数据的线程。

第一个和最后一个线程非常慢,因为它们受I / O限制(硬盘速度慢,网络连接更差)。 在数据库中插入数据是一项非常复杂的任务(分配空间,更新索引,检查外键)

使用不同的工作线程可以提供很多优势:

  1. 分别测试每个线程很容易。 由于它们不共享数据,因此无需同步。 队列将为您做到这一点
  2. 您可以快速更改每个步骤的线程数以调整性能

multithreading可能有所帮助,如果线路不相关,您可以开始两个进程,一个读取偶数行,另一个不均匀的行,并从连接池(dbcp)获取数据库连接并分析性能。 但首先我要调查jdbc是否是最好的方法,通常数据库已经优化了这样的导入解决方案。 这些解决方案还可以临时切换对表的约束检查,并在以后将其重新打开,这对性能也很有帮助。 一如既往地视您的要求而定。

您也可以查看专为批处理设计的弹簧批量。

据我所知,JDBC Bridge使用同步方法序列化对ODBC的所有调用,因此使用mutliple线程不会给你任何性能提升,除非它提升你的应用程序本身。

我不是那么熟悉JDBC,但是对于你的问题的multithreading位,你应该记住的是并行处理依赖于有效地将你的问题分成彼此独立的位,并以某种方式将它们重新组合在一起(他们的输出是)。 如果你不知道任务之间的底层依赖关系,你可能最终会在代码中出现奇怪的错误/exception。 更糟糕的是,它可能都没有任何问题地执行,但结果可能与真实值不同。 multithreading是一项棘手的业务,在学习方面很有趣(至少我是这么认为),但当事情向南发展时,脖子上会感到痛苦。

以下是一些可能有用的链接:

  • Oracle的java trail :最佳起点
  • 一个很好的java并发教程
  • 一篇关于并发的有趣文章

如果你认真考虑进入multithreading,我可以推荐GOETZ,BRIAN:JAVA CONCURRENCY,真是太棒了……

祝好运

我有类似的任务 。 但就我而言,所有表格都是彼此无关的。

第1步:使用SQL Loader(Oracle)将数据上传到数据库(非常快)或任何类似的数据库批量更新工具。

第2步:在不同的线程(针对不相关的任务)和单个线程中运行每个上载过程以执行相关任务。

PS您可以在应用程序中识别不同的相互关联的作业,并将它们分组; 并在不同的线程中运行每个组。

运行你的链接:

JAVA线程遵循上面链接中的最后一个示例(示例:使用多个线程对大型任务进行分区)

SQL Loader可以显着提高性能

我发现将大量记录插入Oracle的最快方法是使用数组操作。 请参阅“setExecuteBatch”方法,该方法特定于OraclePreparedStatement。 它在这里的一个例子中描述: http : //betteratoracle.com/posts/25-array-batch-inserts-with-jdbc

如果multithreading会使您的工作复杂化,您可以使用Async消息传递。 我不完全清楚你的需求是什么,所以,以下是我目前所看到的。

  1. 创建一个文件读取器java,其目的是读取biz文件并将消息放入服务器上的JMS队列。 这可能是普通的Java with static void main()
  2. 在消息驱动的bean中使用JMS消息(如果你有多个服务器,可以设置池中创建的bean数量限制,50或100,具体取决于需要),你的工作现在已经拆分了进入多个服务器。
    1. 每行数据在每台服务器上的2个服务器和50个bean之间异步分配。

您不必在整个过程中处理线程,JMS是理想的,因为您的数据在事务中,如果在您向服务器发送确认之前某些事情失败,则消息将重新发送给消费者,负载将被拆分服务器之间没有你做任何特殊的事情,如multithreading。

此外,spring提供春季批次,可以帮助您。 http://docs.spring.io/spring-batch/reference/html/spring-batch-intro.html#springBatchUsageScenarios