Top Banner
WebLogic JDBC & Transaction 版精华总结 第 1 页总 31 页 BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有 WebLogic JDBC & Transaction 版精华帖整理 崔飞飞 (DEV2DEV ID:CONVERSE) 除了论坛内的精华内容,增加了一些 WEBLOGIC JDBC 的基础配置知识。论坛内有许多 问题是没有回答和解决的,对于这部分内容如果有相类似的就进行归类,其他的就通过查找 相关的资料进行回答,实在解决不了的,整理的时候都做了记录。 整理的过程中对很多原先不清晰的概念,有了更清晰深刻的理解,希望整理后的内容也 能对大家起到这样的作用,限于本人的水平,如有不正确或遗漏之处请大家补充完善。
31

WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

Mar 15, 2018

Download

Documents

hakiet
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 1 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

WebLogic JDBC & Transaction 版精华帖整理

崔飞飞 (DEV2DEV ID:CONVERSE)

除了论坛内的精华内容,增加了一些 WEBLOGIC JDBC 的基础配置知识。论坛内有许多

问题是没有回答和解决的,对于这部分内容如果有相类似的就进行归类,其他的就通过查找

相关的资料进行回答,实在解决不了的,整理的时候都做了记录。

整理的过程中对很多原先不清晰的概念,有了更清晰深刻的理解,希望整理后的内容也

能对大家起到这样的作用,限于本人的水平,如有不正确或遗漏之处请大家补充完善。

Page 2: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 2 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

目 录

WebLogic JDBC & Transaction 版精华帖整理 ............................................................................1 目 录 ..............................................................................................................................................2 1 JDBC 连接池配置 .........................................................................................................................4

1.1 配置连接池 FOR WEBLOGIC 8.1 ..................................................................................4

1.1.1 通过程序配置连接池.............................................................................................7 1.1.2 通过程序查看连接池运行状态信息 .....................................................................7

1.2 配置连接池常见问题........................................................................................................8

1.2.1 连接有效性测试选项.............................................................................................8 1.2.2 不同类型驱动的区别与选择 ..................................................................................8 1.2.3 JDBC 连 SQL SERVER 数据库的常见问题........................................................10 1.2.4 XA-DRIVER 与普通 DRVIER 的区别 ................................................................11

2 JDBC 连接池使用 .......................................................................................................................12

2.1 数据库连接方法总结......................................................................................................12

2.2 数据库连接池使用常见问题..........................................................................................13

2.2.1 连接泄漏(pool connection leak).......................................................................13 2.2.2 处理 ORACLE 的 BLOB 字段 .............................................................................15 2.2.3 配置连接池成功程序使用出问题 ........................................................................16

3 事务处理......................................................................................................................................17

3.1 事务的属性和基本概念..................................................................................................17

3.1.1 Local transaction 和 Distributed transaction 有什么区别? ...................................17 3.1.2 跨资源的 Transaction 如何控制? .......................................................................18 3.1.3 XA 的 driver,是否也是一种 distribued transaction? .......................................18 3.1.4 JTA 和 JTS 到底有什么区别? .............................................................................19 3.1.5 分布式事务提交或回滚后恩能够否关闭连接? ...............................................19

4 论坛常见问题..............................................................................................................................20

4.1 有谁说说 DriverManger 的性能和 DataSource 的区别? ..........................................20

4.2 PreparedStatement 和 Statement 的区别在什么地方? ..........................................20

4.3 解释一下 connection pool 中的 physical connection 和 logic connection 的

区别.........................................................................................................................................20

4.4 连接池中连接使用出错: connection reset by peer, 原因? ............................21

4.5 数据库链接资源该怎么优化?........................................................................................21

4.6 如果页面没有执行到关闭连接的地方,页面被关闭,如何去释放这个建立的连接?

Page 3: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 3 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

................................................................................................................................................21

5 附录 ............................................................................................................................................23

5.1 代码 1---连接池设置代码.............................................................................................23

5.2 代码 2---连接池监控代码.............................................................................................24

Page 4: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 4 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

1 JDBC 连接池配置

1.1 配置连接池 FOR WEBLOGIC 8.1

论坛内经常有人询问如何配置连接池的问题,这里把配置的详细过程都再重复一遍,并

包含论坛内对配置连接池出现的问题回答进行整理。

STEP 1: 数据库类型和驱动类型的选择,对于各种 TYPE 的驱动附录内容会做介绍。

STEP 2:连接池连接属性配置,连接 URL,用户名/密码,数据库服务名。

Page 5: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 5 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

STEP 3:测试连接池配置是否正确。

STEP 4:测试成功后进行部署。

STEP 5:部署成功,选择该连接进行连接池的参数配置。

Page 6: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 6 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

STEP 6:连接池的参数配置。 配置完成后在 config.xml 文件中对应的各属性解释如下:

• Initial Capacity:创建连接池时所创建的数据库连接的数目。

• Maximum Capacity: 连接池中连接的 大数目。

• Capacity Increment: 连接池容量在 大容量限制范围内的增量。

• LoginDelay: 在创建每个物理数据库连接之前要延迟的秒数。

• Allow Shrinking: 将该项设置为 true 时,如果没有使用额外的连接,则允许连接池把

容量减小到 InitialCapacity。

• Shrink Frequency: 在减小连接池容量之前要等待的秒数。如果将 Shrink Frequency

设置为 true,那么也必须将 Allow Shrinking 设置为 true。

• Test Frequency: 数据库连接测试之间间隔的秒数。在每个 Refresh Period 时间间隔之

后,如果设置了 TestTableName,就会使用 TestTableName 测试未使用的数据库连接。

• Test Reserved Connections: 如果选择了这个选项,服务器会在把连接提供给客户端

之前对其进行测试。

• Test Created Connections: 如果选择了这个选项,就会在创建一个 JDBC 连接之后和

在把它添加到 JDBC 连接池中的可用连接列表之前,对该 JDBC 连接进行测试。

• Test Released Connections: 如果选择了这个选项,服务器就会在把连接返回给连接池

之前对其进行测试。

Page 7: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 7 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

• Test Table Name: 用于 JDBC 连接测试的数据库表名。如果指定了 Test Frequency,

并且选择了 Test Reserved Connections、Test Created Connections 或 Test Released

Connections,则 Table Name 是必需的。

• Weblogic.codeset=GBK:编码格式

1.1.1 通过程序配置连接池

配置连接池可以通过weblogic.management.configuration.JDBCConnectionPoolMBean或者

是 weblogic.management.configuration.JDBCDataSourceMBeanl 编程进行。

具体代码见附录部分—代码 1(连接池设置)

1.1.2 通过程序查看连接池运行状态信息

配置连接池可以通过weblogic.management.configuration.JDBCConnectionPoolMBean或者

编程获取运行态的信息。

具体代码见附录部分—代码 2(连接池监控)

Page 8: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 8 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

1.2 配置连接池常见问题

1.2.1 连接有效性测试选项

Q: 连接池配好后,启动正常,如果 Connection Pool 在使用过程中与数据库的联系因为网络

的问题或别的原因断掉,是不是必须重新启动 weblogic 才能重新让 Connection Pool 连上数

据库?我现在每次一碰到数据库连不上就要重启一次 wlsServer,烦得要命。

此类问题出现的原因:

应用服务器到数据库端的网络连接不可靠 ;

数据库在系统运行的情况下重启动;

驱动程序的问题造成连接不可用。

A: WLS 里设置连接的检查,一个是获取连接的时候检查该连接是否有效,另外一个就是释

放连接的时候检查。这两个检查在配置连接池的时候都是可以设置的。

设置的参数说明:

参数名称 参数说明 参数选择值

TestConnectionsOnReserve 从连接池获取连接后是否进行有效性测试 True/false

RefreshMinutes parameter 设定 connection pool 的刷新时间 刷新的时间间隔

Test Table Name 测试的表名,也可以指定 SQL 表名或者是 SQL

1.2.2 不同类型驱动的区别与选择

Q: 请教 console 中连接池的 oracle 驱动程序那个多,用哪个好呢?他们的驱动程序文件分

别对应 LIB 目录下的哪个文件?

A: BEA_HOME$/weblogic81/server/lib 目录内,如果需要连接不同的数据库需要把对应的驱

动程序置于该目录内。

JDBC 驱动的类型与选择,在配置连接池的时候进行选择。

Page 9: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 9 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

JDBC-1 图 JDBC-2 图

【TYPE 1:JDBC-ODBC 桥】

JDBC-1 图左边的分支称为 TYPE 1,即通常由 Sun 公司提供的 JDBC-ODBC 桥接器。

它提供了经由一种或多种 ODBC 驱动进行访问的 JDBC 接口,而 ODBC 驱动,在很多情况

下也即数据库的客户端,必须加载到客户机。因而,它适用于下载和自动安装 Java 程序不

重要、实验用途或者没有其它 JDBC 驱动可用的情况下。执行效率比较低,对于那些大数据

量存取的应用是不适合的.而且,这种方法要求客户端必须安装 ODBC 驱动,所以对于基

于 internet ,intranet 的应用也是 不 合适的 . 因 为 , 不可 能 要求所 有 客户都 能 找到

ODBC DRIVER。

【TYPE 2:本地 API 驱动】

JDBC-1 图右边的分支成为模式 2,类似于 JDBC-ODBC 桥接器,需要加载到客户机,

却是一个部分用 Java 实现的驱动接口。它将 JDBC 调用转换为对数据库(Oracle、Sybase、

Informix、DB2 等)客户端接口的调用。这种驱动比起 TYPE 1 执行效率大大提高了,但它

仍然需要在客户端加载数据库厂商提供的代码库。这样就不适合基于 internet 的应用。

【TYPE 3:网络协议驱动】

JDBC-2 图右边的分支称为 TYPE 3,它同样是一个纯 Java 驱动,不同于 TYPE 4 的是

基于网络协议。它的机制是将 JDBC 调用转换为中间网络协议,然后转换为 DBMS 协议。

中间网络协议层起到一个读取数据库的中间件的作用,能够连接许多类型的数据库,因而是

灵活的 JDBC 模式。这种模式的产品比较适用于企业内部互联网,如若支持国际互联网,

还需添加对安全、穿过防火墙访问等的支持。

Page 10: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 10 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

【TYPE 4:本地协议驱动】

图 2 左边的分支称为 TYPE 4,它一般是数据库厂商才能实现的纯 Java 的基于本地协议

的驱动,直接调用 DBMS(数据库管理系统)使用的网络协议,对于企业内部互联网来说,

是一个实用的解决方案。

1.2.3 JDBC 连 SQL SERVER 数据库的常见问题

使用 TYPE4 类驱动程序,目前支持两种版本的 SQL SERVER

WebLogic jDriver for Microsoft SQL Server Version 7.0 and 2000, 这个版本的驱动是

WEBLOGIC 的默认设置,不需要做其他的配置。

支持 SQL Server 7.0 和 2000.

支持新的数据类型 SQL Server Version 7.0 and 2000.

WebLogic jDriver for Microsoft SQL Server Versions 6.5 and 7.0, 使用这个版本的驱动,必

须在 CLASSPATH 路径里增加 ssqlserver4v65.jar。

支持 SQL Server 6.5.

支持 SQL Server 7.0 但有以下两个限制: 一,是否按照 6.5 的语义规则 creates

columns that do not allow null values. (This behavior is normal for SQL Server version

6.5.)。 二,不支持新的 SQL Server 7.0 数据类型。

知道了以上两点后,有些问题就能很明确了。

Q: ClassNotFoundException 的错误。该错误主要是没有加载 SQL SERVER 的驱动程序。

A: JDBC 连接 SQL SERVER 需要三个包:msutil.jar,msbase.jar,mssqlserver.jar,可以把这三个

包拷贝到 BEA_HOME$/weblogic81/server/lib 目录内。

Q: [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket 的错误。该错误主要

是没有加载 SQL SERVER 的驱动程序。

A: 启动 sqlserver2000 的服务器网络实用工具后,确保 Tcp/Ip 协议已启动,默认的应该都启

动了,这是进行通讯的条件,再选中 Tcp/Ip 协议后点击属性,就看到了一个默认端口号,

这就是你在 getConnection 里用到的端口号,必须把程序里用到的端口号,写成这里的值。

Q: 连接 SQL SERVER 正常,但连接后不能使用或提示 SQL 错误。

A: 该问题主要原因可能是没有给这个用户分配足够的权限,或者你的 SQL 语句中用到了

SQL SERVER 里保留的关键字。

Page 11: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 11 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

Q: 错误:java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Can't start a cloned connection while in manual transaction mode.

A: 这个错误产生的原因一般是当你在一个 SQL SERVER 的 JDBC 连接上执行多个

STATEMENTS 的操作,或者是手动事务状态(AutoCommit=false) 并且使用 direct (SelectMethod=direct) 模式. Direct 模式是默认的模式. 解决办法 当你使用手动事务模式时,必须把 SelectMethod 属性的值设置为 Cursor(SelectMethod= Cursor), 或者是确保在你的连接上只有一个 STATEMENT 操作。

1.2.4 XA-DRIVER 与普通 DRVIER 的区别

Q:XA 的 Driver 和普通的 Driver 有什么区别呢?

A: XA 的 Driver 支持分布式的事务处理,这是与 non xa driver 的 大区别;JDBC2.0 规范提

供了进行分布式事务的能力。分布式事务是个单独的事务,可以应用在位于分离服务器上的

多 个 异 构 数 据 库 。 为 了 支 持 分 布 式 事 务 , JDBC2.0 提 供 了 两 个 新 的 接 口 :

javax.sql.XADataSource 和 javax.sql.XAConnection。从性能的考虑来说,使用 XA 的 DRIVER

会比普通的 DRIVER 慢。

Q: XA 的连接池,选择了支持本地事务后,是否还支持对全局的操作?

A: 8.1既支持TX,也支持Non-Tx的,Weblogic对所有的已知数据库进行了包装(Wrapper),使接

口一致,然而对不同的数据库,根据选择的驱动程序不同,都作了相应的优化和处理。建立数据

源时,如果选择 Non-Tx 类型,那么它参与到 JTA 事务中也不会出错,因为 Weblogic 会启动本地

事务,但是前提是必须有一个资源(XAResource)参与到事务中(多个资源的话必须打开模拟两

阶段提交协议,不然会出错),但是选择 Tx 类型的就必须有一个全局事务,除非选择支持本地

事务(SupportsLocalTransaction=true)。另外如果使用了本地事务,就必须设置 autocommit 为

true,或者手工 commit/rollback。

1.3 配置连接池连接 Oarcle RAC 集群。

前提条件必须使用 WebLogic Server version 8.1SP3 或者是更新的版本。

更详细的内容请查看

http://e-docs.bea.com/wls/docs81/jdbc/oracle_rac.html

Page 12: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 12 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

2 JDBC 连接池使用

2.1 数据库连接方法总结

数据库名称 连接串

MySQL Class.forName("org.gjt.mm.mysql.Driver");

DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName",

sUsr, sPwd );

PostgreSQL Class.forName("org.postgresql.Driver");

DriverManager.getConnection("jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr,

sPwd );

Oracle Class.forName( "oracle.jdbc.driver.OracleDriver" );

DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr,

sPwd );

Sybase Class.forName("com.sybase.jdbc2.jdbc.SybDriver");

DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd );

//(Default-Username/Password: "dba"/"sql")

SQLServer Class.forName( "net.sourceforge.jtds.jdbc.Driver" );

DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr,

sPwd );

ODBC Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );

DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd );

DB2 Class.forName("com.ibm.db2.jdbc.net.DB2Driver");

DriverManager.getConnection("jdbc:db2://192.9.200.108:6789/SAMPLE", sUsr, sPwd );

SAP DB Class.forName ("com.sap.dbtech.jdbc.DriverSapDB");

DriverManager.getConnection ( "jdbc:sapdb://" + host + "/" + database_name,user_name, password)

InterBase Class.forName("interbase.interclient.Driver");

DriverManager.getConnection("jdbc:interbase://localhost/e:/testbed/database/employee.gdb", "sysdba",

"masterkey" );

Microsoft SQL

Server series (6.5,

7.x and 2000) and

Sybase 10

JDBC Name: jTDS

Class.forName("net.sourceforge.jtds.jdbc.Driver ");

DriverManager.getConnection("jdbc:jtds:sqlserver://host:port/database","user","password");or

DriverManager.getConnection("jdbc:jtds:sybase://host:port/database","user","password");

IBM AS400 有装 V4R4 以上版本的 Client Access Express 可以在 C:\Program Files\IBM\Client Access\jt400\lib

找到 driver 档案 jt400.zip,并更改扩展名成为 jt400.jar 语法

java.sql.DriverManager.registerDriver (new com.ibm.as400.access.AS400JDBCDriver ());

Class.forName("com.ibm.as400.access.AS400JDBCConnection");con =

DriverManager.getConnection("jdbc:as400://IP","user","password");

Informix Class.forName("com.informix.jdbc.IfxDriver").newInstance();

String url = "jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver;

user=testuser;password=testpassword";

Page 13: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 13 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

2.2 数据库连接池使用常见问题

2.2.1 连接泄漏(pool connection leak)

造成的原因一般是在使用连接后没有正确的释放连接,或者是释放的过程中出了错误。

【解决办法】

Connection leak是一件令人头痛的而又常见的错误,所以BEA提供了两种方式来解决他。

首先,通过 GC。那些没有被正常关闭的 connection 如果满足可爱的 JVM GC 的条件,GC

会调用 Connection 的 finalize()方法。而从 connection pool 中获取的 connection 是 BEA 包装

过的。所以 WebLogic 会妥善处理这些“孤儿”connection。通过 GC 进行 connection 回收是一

种很被动的做法。BEA 在 WLS 8.1 中主动出击。通过设置 weblogic-ra.xml 中的

inactive-connection-timeout-seconds,BEA 会根据设置,主动关闭那些超时 idle 的 connection。

这就需要 WLS 对以分配出的 connection 进行周期性的检测,来看其是否活动和是否超时。

关于 weblogic-ra.xm 的文档如下:

http://e-docs.bea.com/wls/docs81/jconnector/dtdappen.html#1031211

早 在 WLS 6.1,BEA 就 已 经 在 考 虑 自 动 回 收 “ 孤 儿 ”connection 了 , 这 从

JDBCConnectionPoolRuntimeMBean 的 getLeakedConnectionCount()方法中可见端倪。在

WLS 7.0,8.1 中的 JDBCConnectionPoolRuntimeMBean 中 getLeakedConnectionCount 一直存

在。在 8.1 中,增加了通过设置 idle connection 的 timeout 时间主动关闭 connection 的方式,

手段越来越完全了。

关 于 JDBCConnectionPoolRuntimeMBean 的 详 细 情 况 可 以 参 见 以 下 链 接 :

http://e-docs.bea.com/wls/docs61/javadocs/weblogic/management/runtime/JDBCConnectionPoolRuntimeM

Bean.html

http://e-docs.bea.com/wls/docs70/javadocs/weblogic/management/runtime/JDBCConnectionPoolRuntimeM

Bean.html

http://e-docs.bea.com/wls/docs70/isv/mbeans.html

http://e-docs.bea.com/wls/docs81/javadocs/weblogic/management/runtime/JDBCConnectionPoolRuntimeM

Bean.html

http://e-docs.bea.com/wls/docs81/jdbc/programming.html

在 Dev2Dev 的 Code library 中 已 经 有 了 一 个 例 子 , 通 过 监 听

JDBCConnectionPoolRuntimeMBean 的 LeakedConnectionCount 属性,如若其超过一设定值,

会发出提醒。 http://dev2dev.bea.com/codelibrary/code/jdbc_monitor.jsp

Page 14: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 14 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

在 WLS 7.0 中 已 经 可 以 通 过 GC 收 leaked connection 了 , 不 过

JDBCConnectionPoolRuntimeMBean 的 getLeakedConnectionCount 好像没跟上.

Page 15: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 15 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

2.2.2 处理 ORACLE 的 BLOB 字段

1、在 SQL3 中,定义了一些新的数据类型,包括:

BLOB――二进制大对象,对应 java.sql.Blob 类型。

CLOB――字符大对象,对应 java.sql.Clob 类型。

ARRARY――可以存储多个某特定类型的值,对应 java.sql.Array 类型。

STRUCT――这是任何 SQL 机构类型的缺省映射,对应 java.sql.Struct 类型。

REF――作为数据库中 SQL 数据的引用,可作为参数传入 SQL 语句,对应 java.sql.Ref

类型。

2、java.sql.Blob 和 java.sql.Clob 接口使你能够只把列值加载到内存中。getBlob()和 setBlob()、

getClob()和 setClob(),允许程序员访问 SQL BLOB 和 CLOB 数据类型。BLOB 包含了一个

指向该数据的逻辑指针,而不含数据本身。使用 get 或 set 方法是只返回了一个指向该值得

指 针 , 应 用 程 序 可 以 读 取 所 需 的 一 些 或 全 部 数 据 。 用

weblogic.jdbc.vendor.oracle.OracleThinBlob 对 象 替 代 oracle.sql.BLOB 应 该 直 接 读 取

binayStream,如果采用 OCI 方式,即 ORACLE 本身的 API 连结,可以用读取一个 Blob 对象,然

后转换成输出流,而如果用 thin,即通用的 JDBC,应该用标准的 getBinayStream 方法直接读取.

是 的 , 如 果 用 thin , 必 须 直 接 用 jdbc, 关 键 是 把 java.sql.ResultSet 换 成

oracle.jdbc.driver.OracleResultSet,java.sql.Blob 换成 oracle.sql.BLOB 。

物理连接就是驱动程序中的实现 java.sql.Connection 的对象,逻辑连接就是一个 Wraper,它

实现 Connection 接口,并包含一个物理连接的应用,这采用装饰器设计模式,用户得到的不是

物理连接,而是得到 ConnectionWraper,至于 close()问题,那就稍微难一点,它改变一个标志位,

同时加在 PooledConneciton 上的 ConnectionListener

ORACLE BLOB 字段的处理代码见附录代码 3(来自 BEA 网站的例子代码)

Page 16: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 16 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

2.2.3 配置连接池成功程序使用出问题

常见的主要原因是 JNDI 的名称写错 错误的调用代码: public static java.sql.Connection getConnection () throws java.sql.SQLException {

java.sql.Connection conn = null;

try {

Context ictx = new InitialContext();

Context ctx = (Context) ictx.lookup("java:comp/env"); //这段代码,很多资料介绍里都是这么写的

javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup (DATA_SOURCE);

conn = ds.getConnection();

} catch (Exception e) {

Debug.printErr (e.getMessage ());

throw new SQLException ("Cannot get connection!" + e.getMessage ());

}

if (conn == null) throw new SQLException ("Cannot get connection!");

return conn;

} 正确的应该为: Context ictx = new InitialContext();

javax.sql.DataSource ds = (javax.sql.DataSource) ictx.lookup (DATA_SOURCE);

conn = ds.getConnection();

Page 17: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 17 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

3 事务处理

该部分内容在论坛中占的不多,而且很多问题提的问题都比较模糊,回答的内容就没有

一个比较明确或者是正确的解答,现针对论坛内的问题,把 WEBLOGIC 处理事务的一些基

本概念作个介绍。

3.1 事务的属性和基本概念

Required:

如果在一个事务中调用,就把该方法加到此事务中来,如果还没有启动事务,就启动一

个新事务

RequiredNew:

不管当前有没有事务,都会启动一个新事务,如果当前有事务,会被挂起直到方法结束

NotSupported:

不能在事务中执行此方法。如果有事务,将会被挂起直到方法结束

Supports:

如果当前有事务,此方法会加到当前事务,如果没有,容器也不会启动新事务

Mandatory:

必须在事务中调用此方法,否则抛出异常:TransactionRequiredException

Never:

必须不在事务中调用此方法,否则抛出 RemoteException(远程调用)或 EJBException(本地

调用)

3.1.1 Local transaction 和 Distributed transaction 有什么区别?

Q: 是不是在一个 java VM 上的就是 local 否则就是 distributed?

A: Local transaction 一般指的是单数据源参与的事务。 distributed transaction 指的多数据源

(db)参与的事务.。比如从 db2 中转账到 oracle 中.不是在一个 java VM 上的就是 local 否则就

是 distributed?是不是在一个 jvm 中不是区分 local 和 distribute transaction 的区别。 注意上

面的概念就应该知道了。

Page 18: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 18 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

Q:是否可以在分布事务中使用 non-XA DRIVER?

A: 如果在分布事务系统中只有一个 non-XA DRIVER 的连接池,可以通过配置一个 XA 的

DATASOURCE 来支持。

Q:是否可以在分布事务中使用超过一个的 non-XA DRIVER 的连接池?

A: 不可以。如果这么使用了,当你试图从第二个 non-XA connection pool 中获取连接,

会报如下的一个错误:

"java.sql.SQLException: Connection has already been created in this tx context for pool named <first pool's name>. Illegal attempt to create connection from another pool: <second pool's name>"

3.1.2 跨资源的 Transaction 如何控制?

Q: 如在 transaction 中用到 JMS,又用到 JDBC:在修改数据库后发送 JMS 消息,看文档说只

能用 JTS 的 UserTransaction 来实现,也就是说只能由开发者自己手动来管理事务,而不能

用容器管理事务,是吗?

A: 对于 JMS 来说是的.ejb 本身的事务就是依靠 jta 来支持的,容器管理事务本质上和自己管

理事务是一样的,只不过是容易提供的是一种申明性事务,不需要我们手工管理事务.

3.1.3 XA 的 driver,是否也是一种 distribued transaction?

Q: 资料上讲 distributed transaction 只能用 JTA 的 XAResource 来控制事务,如 JMS 要参加

分布式事务的话就必须用 XA 的。但是,我记得在我们的应用中如果在一个容器管理的事务

中修改两个不同的数据库(这两个库在一台机器的同一个实例中),那么必须用 XA 的 driver,

难道这也是一种 distribued transaction 吗?(它们是同一种资源,都是 JDBC,只是跨库而已,

为什么属于分布式事务呢?)

A: 分布式事务分事务管理器,资源管理器,应用程序,以及底层事务通讯管理.在 xa 中一个 db

就是一个资源.一个 jms 也可以看作是一个资源,事务管理器就是协调这些资源进行统一

commit 或者 rollback 的,所以来说跨库就属于分布式事务了。

Page 19: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 19 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

3.1.4 JTA 和 JTS 到底有什么区别?

JTA 是进行事务调用的 API, JTS 则是事务的具体实现,实现事务管理,资源管理,以

及底层事务通讯管理。

3.1.5 分布式事务提交或回滚后能够否关闭连接?

在事务完成后可以关闭连接。

关于事务更多的内容请参看

http://e-docs.bea.com/wls/docs60/faq/transactions.html

Page 20: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 20 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

4 论坛常见问题

1 到 3 章的内容是针对论坛的常见问题的基本概念说明,很多问题都是由于对概念不了

解造成的,希望 1-3 章的内容能对该论坛内的大部分问题解决有所帮助。

本章开始的内容为论坛内常见问题的解决办法,问题与回答全部来之于论坛,这里只

是做了一个格式与内容的整理。

4.1 DriverManger 的性能和 DataSource 的区别?

DriverManger 直接获取的是物理的连接,通过 Datasource 获得链接是已经存在的物理连接,

通过DriverManger直接获取数据库链接耗费的时间比通过DataSource获得耗费的时间要长。

DriverManager 是管理底层 jdbc 的 API,是 java 初提供的 jdbc api。java2 以后都推荐使

用 Datasource 了。另外,Datasource 提供更高层的接口,这个接口的实现可以是一个链接池。

而 DriverManager 做不到这一点。

4.2 PreparedStatement 和 Statement 的区别在什么地方?

preparedStatement 在大批量的操作数据库的时候可以大大的提高效率,是一种预编译的

方法 , preparedStatement 第一次执行确实比较慢, 对于只执行一次的 SQL 语句选择

Statement是 好的. 相反, 如果 SQL语句被多次执行选用 PreparedStatement是 好的. 使用

prepared 的方式来执行一个查询. JDBC 驱动会发送一个网络请求到数据解析和优化这个查

询. 而执行时会产生另一个网络请求. 对于 Statement, 同一个查询只会产生一次网络到数

据库的通讯. 一班来说 preparedStatement 性能好于 Statement.

4.3解释一下connection pool 中的 physical connection和 logic connection

的区别

这个问题很简单,你看看 Mysql 的 JDBC 驱动就可以了,物理连接就是驱动程序中的实现

java.sql.Connection 的对象,逻辑连接就是一个 Wraper,它实现 Connection 接口,并包含一个物

理连接的应用,这采用装饰器设计模式,用户得到的不是物理连接,而是得到 ConnectionWraper,

Page 21: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 21 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

至于 close()问题,那就稍微难一点,它改变一个标志位,同时同志加在 PooledConneciton 上的

ConnectionListener.

4.4 连接池中连接使用出错: connection reset by peer, 原因?

oracle 8 和 9 的 driver 不通用,还有一种应用操作会导致这种错误:当用户做了某种操作

的申请,但服务还没有响应完,此时用户又重新刷新页面再次申请。

4.5 数据库链接资源该怎么优化?

在页面里要连接数据库进行查询,将取得的结果显示在页面上,在每次查询后都用 close

关闭了连接的。平时的显示正常,在数据库中可以监视得到,创建了一个连接后,查询完了

后很快就释放了,但是在一次查询还没完时,如果在浏览器上很快的按 F5 刷新页面,数据

库的连接会不停的增加,而原来的连接释放很慢,很快就把数据库拖死了。采用连接池也只

能限制总的连接数,如果一个人很快的不停的刷新,数据库不会死了,但很快一个人就把资

源用完了,应用被拖死.

解决办法:

不要把连结建在 BEAN 中,应该写在一个类的静态方法中,然后作为参数传过去,使每个调

用的人都使用同一静态连结.在连结的BEAN中首先看那个静态的连结是否是 null,如果不是,

就直接引用,如果是就重新建立这个连结.

4.6 如果页面没有执行到关闭连接的地方,页面被关闭,如何去释放这个建立的

连接?

一个方法执行,和它是否输出没有任何关系,一个 JSP/SERVLET 在响应时如果要执行很长

时间,而在执行过程中用户关闭了页面,这个 service 方法并不受影响它仍然会执行完成,只是

它的输出被改道了而已,在 JSP/SERVLET 调用和在 BEAN 中调用从效果上说没有任何区别,

只要放在 finlly 块中就一定会释放.

4.7 MutilPool 是什么意思,和 ConnectionPool 有什么区别啊?

Page 22: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 22 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

在单 SERVER 的配置中使用 multipool,主要用途有两个 1>高可靠性;2>负载均衡。可

根据实际需求选择其一。Multipool 的高可靠性只用于数据库停止的一种情况,当数据库挂

起或数据库连接用光时都不起作用。

4.8 weblogic 里数据源和连接池的关系是什么?

连接池可以看作是存储一群连接对象的容器,而数据源是得到一个连接的统一接口.

4.9 配置连接池连接 Oarcle RAC 集群

BEA 官方资料:http://e-docs.bea.com/wls/docs81/jdbc/oracle_rac.html

Page 23: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 23 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

5 附录

5.1 代码 1---连接池设置代码

public void deployServerDataSource(){ try { ctx = getInitialContext(); if(ctx!=null){ this.txtareaDeployStatus.append("\r\n"+"_INFO : 连接服务器,并登陆成功"); this.txtareaDeployStatus.append("\r\n"+"_INFO : 获取管理对象"); //getting the Administration MBeanHome mbeanHome = (MBeanHome)ctx.lookup(MBeanHome.ADMIN_JNDI_NAME); this.txtareaDeployStatus.append("\r\n"+"_INFO : 获取 Admin Server"); serverMBean = (ServerMBean)mbeanHome.getAdminMBean(serverName, "Server"); this.txtareaDeployStatus.append("\r\n"+"_INFO : 获取 domain"); domainName = mbeanHome.getDomainName(); }else{ this.txtareaDeployStatus.append("\r\n"+"_INFO : 连接服务器失败,请服务器正确启

动,并且登陆正确"); return; } } catch (Exception ex) { this.txtareaDeployStatus.append("\r\n"+"_ERROR: 初始化管理服务器信息失败,配置

终止"); return; } try{ this.txtareaDeployStatus.append("\r\n"+"_INFO : 开始配置 WebLogic DataSource of RiseNet"); config(); this.txtareaDeployStatus.append("\r\n"+"_INFO : 配置 WebLogic DataSource of RiseNet 成功 "); JOptionPane.showMessageDialog(this, "配置 WebLogic DataSource of RiseNet 成功", null, JOptionPane.INFORMATION_MESSAGE); }catch(Exception ex){ this.txtareaDeployStatus.append("\r\n"+"_ERROR: 配置 WebLogic DataSource of RiseNet 失败 "); JOptionPane.showMessageDialog(this, "配置 WebLogic DataSource of RiseNet 失败", "

Page 24: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 24 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

错误", JOptionPane.ERROR_MESSAGE); } //需要在配置完以后,进行一次连接测试。 try{ javax.sql.DataSource ds = null; ds = (javax.sql.DataSource)ctx.lookup(cpDataSourceJNDIName); java.sql.Connection c = ds.getConnection(); c.close(); }catch(Exception ex){ this.txtareaDeployStatus.append("\r\n"+"_ERROR: 测试失败 "); this.txtareaDeployStatus.append("\r\n"+"_ERROR: 请手动进行 Apply 一次,否则配置

DataSource 在服务器重新启动后失效 "); JOptionPane.showMessageDialog(this, " 测 试 失 败 ", " 错 误 ", JOptionPane.ERROR_MESSAGE); } } public void config() throws Exception{ cpPoolName = this.txtPoolName.getText(); cpDataSourceName = this.txtDataSourceName.getText(); cpDataSourceJNDIName = this.txtDataSourceJNDIName.getText(); //将原有的连接 DataSource 信息删除 deleteDataSource(); try { createDataSource(); } catch (Exception ex) { ex.printStackTrace(); throw ex; } }

5.2 代码 2---连接池监控代码

package converse; import javax.management.DynamicMBean; import weblogic.management.Helper; import weblogic.management.MBeanHome; public class MonitorBea { private static MonitorBea _Monitor = null; private static MBeanHome adminHome; public MonitorBea() { } //获取当前的活动连接

Page 25: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 25 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

public static int getDBPoolCurrentCount(String s) { try { weblogic.management.runtime.RuntimeMBean runtimembean = adminHome. getRuntimeMBean(s, "JDBCConnectionPoolRuntime"); return Integer.parseInt(runtimembean.getAttribute( "ActiveConnectionsCurrentCount").toString()); } catch (Exception exception) { return -1; } } //获取当前的 FREE HEAP 大小 public static int getVMHeapFreeCurrent(String s) { try { weblogic.management.runtime.RuntimeMBean runtimembean = adminHome. getRuntimeMBean(s, "JVMRuntime"); return Integer.parseInt(runtimembean.getAttribute("HeapFreeCurrent"). toString()); } catch (Exception exception) { return -1; } } //获取执行队列内总线程数和 IDLE 线程数 public static int getExeQueueCount(int i) { try { weblogic.management.runtime.RuntimeMBean runtimembean = adminHome. getRuntimeMBean("default", "ExecuteQueueRuntime"); if (i > 0) return Integer.parseInt(runtimembean.getAttribute( "ServicedRequestTotalCount").toString()); else return Integer.parseInt(runtimembean.getAttribute( "ExecuteThreadCurrentIdleCount").toString()); } catch (Exception exception) { return -1; } } public static boolean InitMonitor(String s, String s1, String s2) { try { adminHome = Helper.getAdminMBeanHome(s1, s2, s); }

Page 26: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 26 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

catch (Exception exception) { return false; } return true; } } 查看的 JSP 页面 <%@ page contentType="text/html; charset=GBK" %> <%@ page import="converse.*" %> <meta HTTP-EQUIV="REFRESH" CONTENT="15;URL=./monitor.jsp"> <HTML> <TITLE>普通用户监控</TITLE> <BODY BGCOLOR="#CCCCCC" TEXT="#000000"> <% //t3://192.168.100.65:20000 String _sURL6 = "t3://192.168.100.65:20000"; //IP 地址和端口号 String _user6 = "weblogic"; //应用服务器用户名 String _pass6 = "password"; //密码 String _serverName6 = "m2"; //服务名 String _dbPool6 = "10000"; //连接池名称 out.println("<br><br><hr>"+_sURL6); if (MonitorBea.InitMonitor(_sURL6,_user6,_pass6)) { //out.println("data + \r\n" ); out.print("\tHeapFreeCurrent=" + MonitorBea.getVMHeapFreeCurrent(_serverName6)/1024/1024 + "(M)"); out.print("\toraclePool=" + MonitorBea.getDBPoolCurrentCount(_dbPool6)); out.print("\tTotalCount=" + MonitorBea.getExeQueueCount(1)); out.print("\tCurrentIdle=" + MonitorBea.getExeQueueCount(0)); } %> </BODY> </HTML>

Page 27: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 27 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

5.3 代码 3---存取 ORACLE 大字段代码

package examples.jdbc.oracle; import java.io.ByteArrayInputStream ; import java.io.InputStream; import java.io.OutputStream; import java.lang.ArrayIndexOutOfBoundsException; import java.sql.*; import java.util.Properties; import weblogic.jdbc.common.OracleBlob; import weblogic.jdbc.common.OracleClob; /** * This example demonstrates the use of Oracle Blob and Clob datatypes. The example creates a database connection * using the Oracle Thin driver and then creates a table with a * BLOB column and a CLOB column. It then inserts an empty BLOB and CLOB, creates a byte array to stream and * store as a BLOB and inserts it in the table, creates a string to store as a CLOB, and then inserts it into the table. */ public class OracleBlobClob { /** * Main method * * @throws Exception */ public static void main(String argv[]) throws Exception { String user = "scott"; String password = "tiger"; String server = "DEMO"; try { for (int i = 0; i < argv.length; i++) { if (argv[i].equals("-user")) { i++; user = (argv[i].equals("null") ? "" : argv[i]); } else if (argv[i].equals("-password")) {

Page 28: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 28 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

i++; password = (argv[i].equals("null") ? "" : argv[i]); } else if (argv[i].equals("-server")) { i++; server = (argv[i].equals("null") ? "" : argv[i]); } } } catch(ArrayIndexOutOfBoundsException aiobe) { System.err.println("\nUsage: java examples.jdbc.oracle.OracleBlobClob [options] \n\n" + "where options include:\n" + " -user <user> User name to be passed to database.\n" + " -password <password> User password to be passed to database.\n" + " -server <server> DNS name of database server.\n"); System.exit(1); } java.sql.Blob myBlob = null; java.sql.Clob myClob = null; Connection conn = null; // get a connection to the Oracle DBMS // substitute the name of the machine hosting your // Oracle server for myOracle8Server Properties props = new Properties(); props.put("user", user); props.put("password", password); props.put("server", server); try { Driver myDriver = (Driver) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); conn = myDriver.connect("jdbc:oracle:thin:" , props); // set Oracle's Auto Commit feature to false. // This is necessary when manipulating Blobs and Clobs. conn.setAutoCommit(false);

Page 29: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 29 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

// ============== Create Table ================== // Create a table with a Blob and Clob column try { // if table does not exist, create it. Statement crstmt = conn.createStatement(); System.out.println("\nCreating table with Blobs and Clobs..."); crstmt.execute("create table lobtest (id int, blobcol Blob, clobcol Clob)"); crstmt.close(); } catch (Exception e) { System.out.println("Exception: " + e); System.out.println("Table already exists. Dropping it and re-creating..."); Statement crstmt2 = conn.createStatement(); crstmt2.execute("drop table lobtest"); crstmt2.execute("create table lobtest (id int, blobcol Blob, clobcol Clob)"); crstmt2.close(); } System.out.println("Table created."); // ============== Initializing blob and clob values ================== Statement stmt = conn.createStatement(); System.out.println("\nInserting row with blank blob and clob columns..."); stmt.execute("insert into lobtest values (44,EMPTY_BLOB(),EMPTY_CLOB())"); System.out.println("Row has been inserted."); // ============== Manipulating the Blob column ====================== // get a reference to the Blob column stmt.execute("select * from lobtest where id=44"); ResultSet rs = stmt.getResultSet(); while ( rs.next() ) { myBlob = rs.getBlob("blobcol"); } // Create a byte array and store some data in it System.out.println("\nCreating the following byte array:"); int STREAM_SIZE = 10; byte[] b = new byte[STREAM_SIZE]; for (int i=0; i < STREAM_SIZE; i++) { b[i] = (byte)(40 + (i%20)); // range 40-60 System.out.println("byte[" + i + "] = " + b[i]); } // Write the byte array to a stream and store it in the Blob column

Page 30: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 30 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

System.out.println ("\nWriting the byte array to a stream" + " and storing it in the table as a blob..."); InputStream is = new ByteArrayInputStream(b); OutputStream os = ((oracle.sql.BLOB) myBlob).getBinaryOutputStream(); byte[] inBytes = new byte[STREAM_SIZE]; int numBytes = is.read(inBytes); // write the input stream to the output stream while (numBytes > 0) { os.write(inBytes, 0, numBytes); numBytes = is.read(inBytes); } // The flush() method causes the data to be written to the table os.flush(); // read back the blob System.out.println("\nReading the blob back from the table and displaying:"); Statement readblob = conn.createStatement(); readblob.execute("select * from lobtest where id=44"); ResultSet rsreadblob = readblob.getResultSet(); // read the blob into a byte array and display byte[] r = new byte[STREAM_SIZE]; while ( rsreadblob.next() ) { Blob myReadBlob = rsreadblob.getBlob("blobcol"); java.io.InputStream readis = myReadBlob.getBinaryStream(); for (int i=0 ; i < STREAM_SIZE ; i++) { r[i] = (byte) readis.read(); System.out.println("output [" + i + "] = " + r[i]); } } // create some character data to work with String ss = "abcdefghijklmnopqrstuvwxyz"; System.out.println("\nCreated the following string to be stored as a clob:\n" + ss); // ============== Manipulating the Clob column ====================== // get a reference to the clob column stmt.execute("select * from lobtest where id=44"); ResultSet crs = stmt.getResultSet(); while ( crs.next() ) {

Page 31: WebLogic JDBC Transaction - read.pudn.comread.pudn.com/downloads90/ebook/346239/WebLogic... · WebLogic JDBC & Transaction版精华总结 第 2 页总 31页 ... 2.2.2 处理ORACLE

WebLogic JDBC & Transaction 版精华总结 第 31 页总 31 页

BEA dev2dev 中国网站 http://dev2dev.bea.com.cn 版权所有

myClob = crs.getClob("clobcol"); java.io.OutputStream osss = ((oracle.sql.CLOB) myClob).getAsciiOutputStream(); byte[] bss = ss.getBytes("ASCII"); osss.write(bss); osss.flush(); } conn.commit(); // read back the clob System.out.println("\nReading the clob back from the table and displaying:"); Statement readclob = conn.createStatement(); readclob.execute("select * from lobtest where id=44"); ResultSet rsreadclob = readclob.getResultSet(); // read the clob in as and ASCII stream, write to a character array, and display while ( rsreadclob.next() ) { Clob myReadClob =rsreadclob.getClob("clobcol"); java.io.InputStream readClobis = myReadClob.getAsciiStream(); char[] c = new char[26]; for (int i=0 ; i < 26 ; i++) { c[i] = (char) readClobis.read(); System.out.println("output [" + i + "] = " + c[i]); } } // Drop the table and clean up connections System.out.println("\nDropping table..."); Statement dropstmt = conn.createStatement(); dropstmt.execute("drop table lobtest"); System.out.println("Table dropped."); } catch (Exception e) { System.out.println("Exception was thrown: " + e.getMessage()); throw e; } finally { try { if (conn != null) conn.close(); } catch (SQLException sqle) { System.out.println("SQLException was thrown: " + sqle.getMessage()); throw sqle; } } } }