Bo's Oracle Station

【博客文章2023】使用Oracle Universal Connection Pool在RAC上执行DML语句

2023-3-20 11:05| 发布者: admin| 查看: 41| 评论: 0|原作者: Author: Bo Tang

摘要: 本文展示了DML语句的insert/delete/update如何包装在Java中,通过Oracle Universal Connetion Pool在Oracle数据库中执行。在RAC数据库中开辟更大的连接池执行PL/SQL的存储过程也有介绍。
【博客文章2023】使用Oracle Universal Connection Pool在RAC上执行DML语句

Author: Bo Tang

1. ant和jdk编译环境的安装:

    在操作系统上,以root用户使用yum命令,安装操作系统光盘里所提供的ant程序包:

[root@station3 ~]# yum list ant
已加载插件:refresh-packagekit, security, ulninfo
base                                                                                   | 3.7 kB     00:00     
已安装的软件包
ant.x86_64                                         1.7.1-15.el6                                          @base

   设置oracle用户的/home/oracle/.bash_profile环境变量:

# .bash_profile


# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi


# User specific environment and startup programs


PATH=$PATH:$HOME/bin


export PATH

export JAVA_HOME=/u01/app/oracle/product/12.2.0/dbhome_1/jdk

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/12.2.0/dbhome_1

export ORACLE_SID=c01orcl1

export NLS_LANG=american_america.AL32UTF8

export ORACLE_TERM=xterm

export EDITOR=vi

export PATH=/u01/app/oracle/product/12.2.0/dbhome_1/jdk/bin:$ORACLE_HOME/bin:$PATH

export LANG=en_US

   在数据库中,准备一个hr用户的存储过程:


2. 创建ant的目录结构和build.xml文件:

    在/home/oracle目录下创建一个目录,目录名任意。在该目录下创建以下子目录和空白文件(蓝色为目录)
    
    分别说明如下:
    在其中lib目录中 ,拷贝ORACLE_HOME/ucp和其他目录下的如下类库jar文件

[oracle@station3 TestProcedure]$ cd lib/

[oracle@station3 lib]$ ls -l

total 9020

-rw-r--r--. 1 oracle oinstall 4409400 Mar 10 14:09 ojdbc8-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall  156242 Mar 10 14:09 ons-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall  305621 Mar 10 14:09 oraclepki-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall 1663954 Mar 10 14:09 orai18n-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall  459867 Mar 10 14:09 orajsoda-1.1.4.jar

-rw-r--r--. 1 oracle oinstall  210336 Mar 10 14:09 osdt_cert-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall  312199 Mar 10 14:09 osdt_core-19.10.0.0.jar

-rw-r--r--. 1 oracle oinstall 1688939 Mar 10 14:09 ucp-19.10.0.0.jar


    lib目录下还会自动放置编连好的最终的jar包。
    MANIFEST.MF为程序说明文件,自己编写。
    src目录下放java源程序。
    classes目录下自动放置编译好的class文件。
    在这里,最重要的文件是build.xml,它指导ant如何编连jar包。下面给出build.xml的内容:

<project name="" default="all" basedir=".">

  <!-- set global properties for this build -->

  <property name="src" location="src"/>

  <property name="classes" location="classes"/>

 

  <target name="all" depends="clean,dist"/>

 

  <target name="init">

    <!-- Create the build directory structure used by compile -->

    <mkdir dir="${classes}"/>

  </target>

 

  <target name="compile" depends="init"

        description="compile the source " >

    <!-- Compile the java code from ${src} into ${classes} -->

    <!-- remove debug information: debug="true" -->

   <javac srcdir="${src}" debug="on" destdir="${classes}">

      <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/ucp-19.10.0.0.jar"/>

      </classpath>

      <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/ojdbc8-19.10.0.0.jar"/>

      </classpath>

      <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/ons-19.10.0.0.jar"/>

      </classpath>

       <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/oraclepki-19.10.0.0.jar"/>

      </classpath>

 <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/osdt_core-19.10.0.0.jar"/>

      </classpath>

      <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/osdt_cert-19.10.0.0.jar"/>

      </classpath>

      <classpath>

        <pathelement path="${classpath}"/>

        <pathelement location="./lib/orai18n-19.10.0.0.jar"/>

      </classpath>  

    </javac>

  </target>

 

  <target name="dist" depends="compile"

        description="Jar the source files" >

    <!-- Create the distribution directory -->

    <delete dir="./lib/Test.jar"/>

    <jar destfile="./lib/Test.jar" basedir="${classes}" excludes="*.xml,*.cdi" manifest="MANIFEST.MF"/>

  </target>

 

  <target name="clean"

        description="clean up" >

    <!-- Delete the ${classes} and ${dist} directory trees -->

    <delete dir="${classes}"/>

    <delete dir="./lib/Test.jar"/>

  </target>

  

</project>


    写一个shell脚本,方便执行编连好的jar程序

#!/bin/bash



java -Doracle.ucp.PlannedDrainingPeriod=30 -classpath ./lib/Test.jar:./lib/ucp-19.10.0.0.jar:./lib/ojdbc8-19.10.0.0.jar:./lib/ons-19.10.0.0.jar:./lib/oraclepki-19.10.0.0.jar:./lib/osdt_cert-19.10.0.0.jar:./lib/osdt_core-19.10.0.0.jar Test.Test 
   
3. 使用Oracle Universal Connection Pool来执行insert语句:

    在src目录下,写一个名为Test.java的程序

package Test;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import oracle.ucp.jdbc.PoolDataSourceFactory; 

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; 

public class Test {
 public static void main(String[] args) throws SQLException, InterruptedException{
  // 1.创建pool类型的数据源
  PoolDataSource dataSource=PoolDataSourceFactory.getPoolDataSource();
  // 2.配置数据源
  dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
  dataSource.setURL("jdbc:oracle:thin:hr/oracle_4U@//scan.cluster3.example.com:1521/serv3.example.com");
  dataSource.setUser("hr");
  dataSource.setPassword("oracle_4U");
  dataSource.setMaxPoolSize(1);
  dataSource.setValidateConnectionOnBorrow(true);
  Connection connection = null;

  for(int i=1;; i++){
   try{
   // 3.通过数据源获取数据库连接(从连接池中获取)
    connection=dataSource.getConnection();
    PreparedStatement statement=connection.prepareStatement("insert into hr.test1 values(?)");
    statement.setInt(1,i);
    statement.executeUpdate();
    // 4.关闭连接(归还到连接池)
    connection.setAutoCommit(false);
    connection.commit();
    connection.close();
    //Thread.sleep(1000*60*3);
   } catch(Exception e){
      //connection.close();
      System.out.println(i+":"+e);
      //Thread.sleep(1000*60*3);
   }
  }
 }
}
   
    在build.xml那层目录,进行ant编连:

[oracle@station3 TestProcedure]$ ls

build.xml  classes  lib  MANIFEST.MF  run.sh  src

[oracle@station3 TestProcedure]$ ant

Buildfile: build.xml

 

clean:

   [delete] Deleting directory /home/oracle/JAVA/DBJar/TestProcedure/classes

 

init:

    [mkdir] Created dir: /home/oracle/JAVA/DBJar/TestProcedure/classes

 

compile:

    [javac] Compiling 1 source file to /home/oracle/JAVA/DBJar/TestProcedure/classes

    [javac] This version of java does not support the classic compiler; upgrading to modern

 

dist:

      [jar] Building jar: /home/oracle/JAVA/DBJar/TestProcedure/lib/Test.jar

 

all:

 

BUILD SUCCESSFUL

Total time: 3 seconds


    运行,由于是一直循环循环,请运行一会后Ctrl+C手工中断:

[oracle@station3 TestInsert]$ ls

build.xml  classes  lib  MANIFEST.MF  run.sh  src

[oracle@station3 TestInsert]$ ./run.sh

^C

[oracle@station3 TestInsert]$ sqlplus /nolog

 

SQL*Plus: Release 12.2.0.1.0 Production on Wed Mar 15 14:22:56 2023

 

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

 

SQL> conn hr/oracle_4U@c01orcl

Connected.

SQL> select  * from test1;

 

         A

----------

         1

         2

         3

         4

         5

         6

         7

         8

         9

        10

        11

 

         A

----------

        12

        13

        14

        15

        16

        17

        18

        19

        20

4. 使用Oracle Universal Connection Pool来执行delete语句:

    只需要改动源代码Test.java,编连和执行过程与insert部分完全一样

package Test;

import oracle.ucp.jdbc.PoolDataSource;

import oracle.ucp.jdbc.PoolDataSourceImpl;

import oracle.ucp.jdbc.PoolDataSourceFactory;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class Test {

 public static void main(String[] args) throws SQLException, InterruptedException{

  // 1.创建pool类型的数据源

  PoolDataSource dataSource=PoolDataSourceFactory.getPoolDataSource();

  // 2.配置数据源

  dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");

  dataSource.setURL("jdbc:oracle:thin:hr/oracle_4U@//scan.cluster3.example.com:1521/serv3.example.com");

  dataSource.setUser("hr");

  dataSource.setPassword("oracle_4U");

  dataSource.setMaxPoolSize(1);

  dataSource.setValidateConnectionOnBorrow(true);

  Connection connection = null;

  for(int i=1;; i++){

   try{

   // 3.通过数据源获取数据库连接(从连接池中获取)

    connection=dataSource.getConnection();

    PreparedStatement statement=connection.prepareStatement("delete from  hr.test1 where a="+i);

    statement.executeUpdate();

    // 4.关闭连接(归还到连接池)

    connection.setAutoCommit(false);

    connection.commit();

    connection.close();

    //Thread.sleep(1000*60*3);

   } catch(Exception e){

      //connection.close();

      System.out.println(i+":"+e);

      //Thread.sleep(1000*60*3);

   }

  }

 }

}


5. 使用Oracle Universal Connection Pool来执行update语句:

    只需要改动源代码Test.java,编连和执行过程与insert部分完全一样

package Test;

import oracle.ucp.jdbc.PoolDataSource;

import oracle.ucp.jdbc.PoolDataSourceFactory;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class Test {

 public static void main(String[] args) throws SQLException, InterruptedException{

  // 1.创建pool类型的数据源

  PoolDataSource dataSource=PoolDataSourceFactory.getPoolDataSource();

  // 2.配置数据源

  dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");

  dataSource.setURL("jdbc:oracle:thin:hr/oracle_4U@//scan.cluster3.example.com:1521/serv3.example.com");

  dataSource.setUser("hr");

  dataSource.setPassword("oracle_4U");

  dataSource.setMaxPoolSize(1);

  dataSource.setValidateConnectionOnBorrow(true);

  Connection connection = null;

  for(int i=1;; i++){

   try{

   // 3.通过数据源获取数据库连接(从连接池中获取)

    connection=dataSource.getConnection();

    PreparedStatement statement=connection.prepareStatement("update hr.test1 set a=a+1");

    statement.executeUpdate();

    // 4.关闭连接(归还到连接池)

    connection.setAutoCommit(false);

    connection.commit();

    connection.close();

    //Thread.sleep(1000*60*3);

   } catch(Exception e){

      //connection.close();

      System.out.println(i+":"+e);

      //Thread.sleep(1000*60*3);

   }

  }

 }

}


6. 使用Oracle Universal Connection Pool来执行PL/SQL存储过程语句:

    只需要改动源代码Test.java,编连和执行过程与insert部分完全一样

package Test;

import oracle.ucp.jdbc.PoolDataSource;

import oracle.ucp.jdbc.PoolDataSourceImpl;

import oracle.ucp.jdbc.PoolDataSourceFactory;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class Test {

 public static void main(String[] args) throws SQLException, InterruptedException{

  // 1.创建pool类型的数据源

  PoolDataSource dataSource=PoolDataSourceFactory.getPoolDataSource();

  // 2.配置数据源

  dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");

  dataSource.setURL("jdbc:oracle:thin:hr/oracle_4U@//scan.cluster3.example.com:1521/serv3.example.com");

  dataSource.setUser("hr");

  dataSource.setPassword("oracle_4U");

  dataSource.setMaxPoolSize(20);

  dataSource.setValidateConnectionOnBorrow(true);

  Connection connection = null;

   // 3.通过数据源获取数据库连接(从连接池中获取)

    connection=dataSource.getConnection();

    PreparedStatement statement=connection.prepareStatement("begin hr.proctest1; end;");

    statement.executeUpdate();

    // 4.关闭连接(归还到连接池)

    connection.setAutoCommit(false);

    connection.commit();

    connection.close();

    //Thread.sleep(1000*60*3);

 }

}


    源代码中,由于存储过程本身循环插入,所以在java部分取消了循环。由于PL/SQL负载较重,如果希望连接池更大,改动源代码中的dataSource.setMaxPoolSize(1)为dataSource.setMaxPoolSize(20)。

路过

雷人

握手

鲜花

鸡蛋

QQ|手机版|Bo's Oracle Station   

GMT+8, 2023-3-25 12:08 , Processed in 0.021040 second(s), 21 queries .

返回顶部