关于weblogic中使用prepared statement cache后操作DDL的问题

前几天有客户问我这么个问题,他们在weblogic中配置了prepared statement cache, 而他们应用中有操作DDL的地方,比如alter table什么的,这时候如果使用cached prepared statement的话,Oracle端会抛出SQLException: 违反协议。其实这个问题,weblogic 文档中已经有描述,如下:

http://e-docs.bea.com/wls/docs81/ConsoleHelp/jdbc_connection_pools.html#1107805

大概意思是:这个依赖数据库,需要看数据库端怎么处理这样的prepared statement. 最初我认为只要在weblogic 端手工清理掉整个cache就可以了(weblogic在prepared statement 出现异常的时候,会主动将wrapper connection上对应的prepared statement cache清掉,下次调用的时候会重建prepared statement,所以手工清理cache是完全多余的),但实际结果并不如想象的那样。即使我们clear掉prepared statement cache, 重新创建一个prepared statement的话,问题同样得不到解决。 为什么? 怎么办?作了几个相关的测试后,结论是:这个行为依赖于DB的physical connection, 而不是单个的prepared statement,出现这样的问题后,能做的有如下2种方式:

1:客户端处理prepared statement抛出的异常, catch到异常后,需要将physical connection拿出来close掉。之所以建议这样,客户从data source中拿出的是个logical connection,而physical connection一直在connection pool。如果简单的close掉logical connection, 重新去拿一个logical connection的话,weblogic无法保证返回的connection用了不同的physical connection。后面会有详细的解决办法。

2:等待,大约一分钟左右,可以正常操作。

首先看看为什么?

好了,我们可以用用下面的代码测试一下:在测试程序run起来以后, 通过sql plus去改变后端test table的结构,比如alter table test  add(key1 varchar(10))

1 package test.jdbc;
2
3 import oracle.jdbc.OracleDriver;
4 import java.sql.DriverManager;
5 import java.sql.Connection;
6 import java.sql.PreparedStatement;
7 import java.sql.ResultSet;
8
9 public class OracleDriverTest {
10
11     public static void main(String args[])
12     {
13         try
14         {
15             OracleDriver driver = (OracleDriver)Class.
16                 forName("oracle.jdbc.OracleDriver").newInstance();
17             DriverManager.registerDriver(driver);
18             String url="jdbc:oracle:thin:@localhost:1521:coffeedb";
19             Connection conn = DriverManager.getConnection(url, "system", "coffee");
20             PreparedStatement pstmt = conn.prepareStatement("select * from Test");
21             for(int loop=0; loop<10; loop++)
22             {
23                 try
24                 {
25                     System.out.println(pstmt.toString());
26                     ResultSet rs = pstmt.executeQuery();
27                     while(rs.next())
28                     {
29                         String val = rs.getString(1);
30                         System.out.println(val);
31                     }
32                     rs.close();
33                     Thread.currentThread().sleep(5000);
34                 }catch(java.sql.SQLException se)
35                 {
36                     //Thread.currentThread().sleep(10000);
37                     se.printStackTrace();
38                     System.out.println("get exception, remake prepared statement in loop: " + loop);
39                     /*
40                      * if we just remake a prepared statement, SQLException will be thrown still, to
41                      * slove such issue, we have to remake a physical connection. To do the test, we
42                      * can comment the next line at first to see what will happen and then we activate
43                      * it, to see what will happen this time. 
44                      */
45                     //conn = DriverManager.getConnection(url, "system", "coffee");
46                     pstmt = conn.prepareStatement("select * from Test");
47                     continue;
48                 }
49             }
50             pstmt.close();
51             conn.close();
52             
53         }catch(Exception e)
54         {
55             try
56             {
57                 //Thread.currentThread().sleep(10000);
58                 System.out.println("catch exception in main()");
59                 e.printStackTrace();
60             }catch(Exception e1)
61             {
62                 e1.printStackTrace();
63             }
64         }
65     }
66 }
67

时间: 2024-09-17 02:26:01

关于weblogic中使用prepared statement cache后操作DDL的问题的相关文章

dbcp继续优化篇(statement cache)

背景    昨天有同事反映,原先用jboss jndi数据源,现在换成基于spring容器的dbcp配置后,发现原先的请求从5ms,增加到7ms,性能下降了50%.   分析    在服务器上观察了一下请求的profile信息,发现一个请求90%多的时间都在mysql处理: 25%为prepared statement,70%为mysql read数据等待.   使用jvisualvm得到的一个time profile的结果:     发现很明显,preparestatement占了比较大的比例

linux c语言刷新cpu cache后,如果判断数据真正从cache拷贝到内存中了?

问题描述 linux c语言刷新cpu cache后,如果判断数据真正从cache拷贝到内存中了? linux c语言刷新cpu cache后,如果判断数据真正从cache拷贝到内存中了? 解决方案 用secureCRT看打印信息啊

JVM TI学习(1) 如何中断weblogic中stuck thread

JPDA(Java Platform Debugger Architecture)是sun推出的一套工具接口,有了这些接口,debugger.profile工具可以attach到target JVM,进而可以监控.调试我们的程序.JPDA包括三部分:JVM TI, JDI, JDWP.TI可以使用native语言,通过调用jvmti.c提供的系列库函数,实现debug工作,而JDI是TI面向Java开发人员提供的高层开发接口.TI代替了早期的DI,每个版本都做了一定的功能增强.随着JDK的发展,

digester+weblogic-Digester+weblogic中digester.parse(input)为null

问题描述 Digester+weblogic中digester.parse(input)为null 代码片段如下: private static void parser() { File input = new File(Configurator.getTransactionConfigFile()); File rules = new File(Configurator.getDigesterRuleFile()); // TODO try { // 创建一个digester对象并制定解析规则

Weblogic中使用Servlet

Weblogic中使用Servlet2001年4月30日                                                                整理人:sglzhh本文当适合于个人开发时使用,项目deploy时会有专门的人负责的为方便起见,请先完成相应的修改后,再启动Weblogic以下操作有些是本来可以在console中完成的,但是由于目前console有些问题,故我们这里直接改动相关文件,以config/mydomain为例子.1.首先,新建一个Web

WebLogic中的一些基本概念

WebLogic 中的基本概念 上周参加了单位组织的WebLogic培训,为了便于自己记忆,培训后,整理梳理了一些WebLogic的资料,会陆续的发出来,下面是一些基本概念. Domain : 域是作为单元进行管理的一组相关的 WebLogic Server 资源.一个域包含一个或多个 WebLogic Server 实例,这些实例可以是群集实例.非群集实例,或者是群集与非群集实例的组合.一个域可以包含多个群集.域还包含部署在域中的应用程序组件.此域中的这些应用程序组件和服务器实例所需的资源和服

应用-dw中,阶段变量添加后为什么绑定不显示

问题描述 dw中,阶段变量添加后为什么绑定不显示 ADODB.Command 错误 '800a0d5d' 应用程序在当前操作中使用了错误类型的值. /order_ch.asp,行 38 MM_editCmd.Parameters.Append MM_editCmd.CreateParameter(""param5"" 5 1 -1 MM_IIF(Request.Form(""price"") Request.Form(&quo

js中的前绑定和后绑定详解

这篇文章详细介绍了js中的前绑定和后绑定,有需要的朋友可以参考一下    其主要意思就是看我有没有用过前绑定,即Dom树中的某些元素在还没有创建出来时,就指定该类型的元素一出生就应该拥有的某些事件.在实际开发过程中经常会涉及到前绑定和后绑定.顾名思义,前绑定--还未出生即绑定了某些事件,后绑定--出生后才会绑定的某些事件. 下面,通过一个简单的例子进行阐述,以供大家参考,并对各个方法进行比较: 页面元素: 复制代码 代码如下: <div id="main"> <a h

Coreldraw中图像与输出位图后大小不一致怎么办

问:Coreldraw中图像与输出位图后大小不一致,怎么办? 在Coreldraw里做图,用100%显示的时候并不觉得大,当导出为JPEG格式时,图像却比在Coreldraw里看到的大出很多.为什么?怎么办? 答: Coreldraw默认分辨率是300象素,如果你输出JPG比这个分辨率小,看起来肯定要大. 输出JPEG格式,要注意分辨率,放网上看看的一般72/96DIP,一般用于打印的150DPI,用于印刷的300DPI以上. 如果想按Coreldraw中的实际大小输出,记得选择1:1,还要在大