Java 关于在jdbc中使用多线程的教程

Java 关于在jdbc中使用多线程的教程,java,multithreading,jdbc,Java,Multithreading,Jdbc,我们公司有一个每天运行的批处理应用程序,它主要做一些与数据库相关的工作,例如将数据从文件导入数据库表 该应用程序中定义了20多个任务,每个任务可能依赖于其他任务,也可能不依赖于其他任务。 应用程序逐个执行任务,整个应用程序在单个线程中运行 完成所有任务需要3~7个小时。我觉得它太长了,所以我想也许我可以通过多线程来提高性能 我认为,由于任务之间存在依赖关系,使任务并行运行并不好(或不容易),但也许我可以使用多线程来提高任务内部的性能 例如:我们有一个定义为“ImportBizData”的任务,它

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

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

完成所有任务需要3~7个小时。我觉得它太长了,所以我想也许我可以通过多线程来提高性能

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

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


由于我对多线程有一点了解,我希望有人能提供一些关于这个主题的教程链接。

多线程可能会有所帮助,如果行不相关,您可以启动两个进程,一个读取偶数行,另一个读取不均匀行,然后从连接池(dbcp)获取db连接并分析性能。但首先我要调查jdbc是否是最好的方法,因为数据库通常都有针对此类导入的优化解决方案。这些解决方案还可以临时切换表的约束检查,稍后再打开,这对性能也有好处。视您的要求而定


此外,您可能还想检查专为批量处理而设计的springbatch。

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

我对JDBC不太熟悉,但关于您问题中的多线程部分,您应该记住的是,并行处理依赖于有效地将问题划分为相互独立的位,并以某种方式将它们重新组合在一起(即它们的输出)。如果您不知道任务之间的底层依赖关系,那么代码中可能会出现非常奇怪的错误/异常。更糟糕的是,它可能会毫无问题地执行,但结果可能与真实值不符。多线程是一项棘手的业务,从某种程度上讲,学习起来很有趣(至少我认为是这样),但当事情变得糟糕时,它会让人头疼

以下是一些可能提供有用信息的链接:

  • :最佳出发地点
如果你真的想努力进入多线程领域,我可以向你推荐GOETZ,BRIAN:JAVA并发,这本书真是太棒了


祝你好运,多线程将提高你的性能,但有几件事你需要知道:

  • 每个线程都需要自己的JDBC连接。无法在线程之间共享连接,因为每个连接也是一个事务
  • 分块上传数据,并每隔一段时间提交一次,以避免累积大量回滚/撤消表
  • 将任务分成多个工作单元,每个工作单元做一项工作
  • 详细说明最后一点:目前,您有一个任务可以读取文件、解析文件、打开JDBC连接、执行一些计算、将数据发送到数据库等

    你应该做什么:

  • 一个(!)线程读取文件并从中创建“作业”。每个作业都应该包含一个小的但不是太小的“工作单元”。把他们排成一队
  • 下一个线程等待队列中的作业并执行计算。当步骤#1中的线程等待较慢的硬盘返回新行数据时,可能会发生这种情况。此转换步骤的结果进入下一个队列
  • 一个或多个线程通过JDBC上传数据
  • 第一个和最后一个线程非常慢,因为它们受I/O限制(硬盘速度慢,网络连接更差)。另外,在数据库中插入数据是一项非常复杂的任务(分配空间、更新索引、检查外键)

    使用不同的辅助线程可以为您带来很多好处:

  • 单独测试每个线程很容易。因为它们不共享数据,所以不需要同步。队列会帮你做到这一点
  • 您可以快速更改每个步骤的线程数以调整性能

  • 我有一个类似的任务。但在我的例子中,所有的表都是互不相关的

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

    步骤2: 在不同的线程(对于不相关的任务)和单个线程(对于相关的任务)中运行每个上载进程

    另外,你可以在申请表中确定不同的相互关联的工作,并将其分组;并在不同的线程中运行每个组

    运行您的链接:

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


    我发现将大量记录插入Oracle的最快方法是使用数组操作。请参阅“setExecuteBatch”方法,该方法特定于OraclePreparedStatement。下面的一个示例对此进行了描述:

    如果多线程会使您的工作复杂化,您可以使用异步消息传递。我不完全了解您的需求,因此,以下是我目前看到的

  • 创建一个文件读取器java,其目的是读取biz文件并将消息放入服务器上的JMS队列。这可能是带有静态void main()的纯Java
  • 使用消息驱动bean中的JMS消息(您可以根据需要设置池中要创建的bean数量的限制,50或100),如果您有多个服务器,那么很好,您的作业现在是拆分的