一次做应用升级出现了一个问题,描述如下:

升级分为两块,一块是数据库结构变更(表结构增加新字段);一块是应用程序的升级。

应用环境为:jboss4.0.5 + ibatis + spring 数据源在jboss的oracle-ds.xml文件中进行配置,通过spring的jndi方式进行查找 。

我先将数据库进行升级,更改表结构(增加字段),因为应用中的ibatis的查询采用的是ResultMap返回方式,返回定义的表结构字段,即使数据库 发生变更,也不会产生影响。于是我大胆的进行脚本的执行。结果当我下午16:00数据库变更之后,几乎在同时就有人反应应用的一些查询功能无法使用,立刻 查看出错日志:

Java代码

Caused by: com.alibaba.generalorm.dao.DataAccessException: Data query error!

--- The error occurred in sqlmap/CiaDissension.xml.

--- The error occurred whileapplying a parameter map.

--- Check the QUERY_ALL_DISSENSION_CATEGORY-InlineParameterMap.

--- Check the statement (query failed).

--- Cause: java.sql.SQLException: OALL8 处于不一致状态

at com.alibaba.ibatis.BasicIBatisDao.query(BasicIBatisDao.java:315)

at com.alibaba.china.rcc.riskdc.dao.DissensionCategoryDAO.getAll(DissensionCategoryDAO.java:40)

at com.alibaba.china.rcc.riskdc.service.impl.DissensionServiceImpl.getCategoryMap(DissensionServiceImpl.java:495)

at com.alibaba.china.rcc.riskdc.service.impl.DissensionServiceImpl.getCategory(DissensionServiceImpl.java:188)

at com.alibaba.china.rcc.riskdc.web.action.DissensionAction.getCategory(DissensionAction.java:263)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at com.alibaba.webx.action.invoker.AbstractModuleMethodInvoker.executeNoArgMethod(AbstractModuleMethodInvoker.java:401)

... 33more

Java代码

Caused by: com.alibaba.generalorm.dao.DataAccessException: Data query error!

--- The error occurred in sqlmap/CiaDissension.xml.

--- The error occurred whileapplying a parameter map.

--- Check the QUERY_ALL_DISSENSION_BUSINESS-InlineParameterMap.

--- Check the statement (query failed).

--- Cause: java.sql.SQLException: 违反协议

at com.alibaba.ibatis.BasicIBatisDao.query(BasicIBatisDao.java:315)

at com.alibaba.china.rcc.riskdc.dao.DissensionBusinessDAO.getAll(DissensionBusinessDAO.java:19)

at com.alibaba.china.rcc.riskdc.service.impl.DissensionServiceImpl.getBusiness(DissensionServiceImpl.java:178)

at com.alibaba.china.rcc.riskdc.web.action.DissensionAction.getBusiness(DissensionAction.java:249)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at com.alibaba.webx.action.invoker.AbstractModuleMethodInvoker.executeNoArgMethod(AbstractModuleMethodInvoker.java:401)

... 33more

为什么会出现违反协议的问题?马上google一下,有些人说是因为数据库的字段类型与java中使用的类型不一致导致,但查看了ibtais的 map文件,老的应用代码根本还没有使用新的的字段!后来找pla共同排查,也没有发现应用程序哪里会出现问题,便打电话给DBA让他查下数据库,DBA 咨询了一位资格较老的DBA,他说以前也出现过这种情况,只要将应用重启下,就好了。马上重启,果然问题解决了,违反协议的错误没有再报。

查找原因:在做升级前,我自己在开发环境也做过模拟,并没有出现如果应用不重启,数据库变更而报“违反协议”的错误。而我看了下发布环境与开发环境差异,唯一的差异是开发环境没有采用jboss+jndi的方式获取数据源,而采用了tomcat+c3p0的方式获取数据源。

于是我开始实验。

Tomcat+C3P0启动方式:

1.准备好更改数据库脚本。

2.在开发环境用tomcat启动应用,并访问到涉及表结构变更的页面。

3.执行数据库脚本,确保表结构发生了变更。

4.刷新在步骤2的页面,查看后台输出和前台页面输出。

5.一切正常,没有抛出违反协议或处于不一致状态的错误日志。

JBoss4.0.5+JNDI启动方式

1.准备好更改数据库脚本。

2.在开发环境用jboss启动应用,并访问到涉及表结构变更的页面。

3.执行数据库脚本,确保表结构发生了变更。

4.刷新在步骤2的页面,查看后台输出和前台页面输出。

5.出现了违反协议和处于不一致状态的问题。

总结:

由此可以看出,出现这个问题与ibatis没有关系,而与数据源的获取方式有关,一种是通过Spring+c3p0直接注入DataSource;一种是在oracle-ds.xml文件中配置,然后在spring中通过jndi的方式进行查找,获取数据源。第二种在数据库变更的情况下,就必须进行应用重启,否则就会抛出违反协议或处于不一致的状态。

但根本原因到底是什么呢?我还在寻找。

===================================================

咨询了大少,并不是因为数据源配置模式没有关系,用c3p0或者jndi等,而是与数据源的配置方式有关:

在oracle-ds的配置如下:

Java代码

rccBopsDataSource

false

jdbc:oracle:thin:@xx.xx.xx.xx:1521:xx

true

50

GBK

ISO-8859-1

com.alibaba.china.jdbc.SimpleDriver

1

14

20

Oracle9i

15

org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter

xx

xx

其中prepared-statement-cache-size参数解释为:

- the number of prepared statements per connection to be kept open and reused in subsequent requests. They are stored in a LRU cache. The default is 0 (zero), meaning no cache.

为每个打开的数据库连接缓存了一定数量的prepared statement.他们是存在LRU cache中,如果设值为0,那么将不缓冲。这里我们设值了每个连接缓存20条prepared statment。

而在c3p0的配置中:

Xml代码

class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

com.mchange.v2.c3p0.DataSources.pooledDataSource

1

1

1

5

1800

1000

30

1000

false

5000

lt;/bean>

上网查了下,影响到preparedStatment cache的参数有两个:maxStatements和maxStatementsPerConnection 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭,默认为0。

继续实验:

1、将c3p0配置增加maxStatements和maxStatementsPerConnection并都设值20。

修改数据库表结构,刷新访问页面。

后台抛出违反协议和处于不一致状态的错误提示。

2.将oracle-ds.xml文件配置更改prepared-statement-cache-size为0。

修改数据库表结构,刷新访问页面。

后台没有抛出违反协议和处于不一致状态的错误提示。

附参考文章:

http://community.jboss.org/wiki/configdatasources   讲解jboss中关于datasource的参数

http://msq.iteye.com/blog/60387   讲解c3p0的详细参数

java sql 违反协议_java.sql.SQLException: 违反协议异常的一种解释相关推荐

  1. tomcat登录违反协议_java.sql.sqlexception: 违反协议

    场景:转:java.sql.SQLException: 违反协议错误的一种解释 转:java.sql.SQLException: 违反协议异常的一种解释 转: java.sql.SQLExceptio ...

  2. java sql2005驱动_java.sql.SQLException:找不到适用于jdbc:microsoft:sqlserver的驱动程序...

    当我尝试运行此程序时,出现此异常.这是微软的例子之一.我已经通过项目属性将sqljdbc4.jar添加到了netbeans的类路径中,以便进行编译和运行.我还测试了可以使用下面的import语句找到该 ...

  3. java语言sql接口_java.sql包中的类和接口及其使用

    java.sql包提供使用Java编程语言访问并处理存储在数据源中数据的API,可以动态地安装不同驱动程序来访问不同数据源. 下面,详解java.sql包中包含的常用的接口和类 1.DriverMan ...

  4. java 关闭语句_java.sql.SQLRecoverableException: 关闭的语句

    数据库连接池配置: 数据库链接在运行时报错: Caused by: java.sql.SQLRecoverableException: 关闭的语句 at oracle.jdbc.driver.Orac ...

  5. java sql 日期_java.sql.Date

    java.sql.Date 1 java.sql.Date介绍 java.sql.Date类仅表示java中的日期.它继承了java.util.Date类. java.sql.Date实例在JDBC中 ...

  6. java statement 存储过程_Java+sql server+CallableStatement调用存储过程三种情况 (转)...

    在JSP页面中进行测试,代码如下: String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs&quo ...

  7. java sql 基础_Java SQL基础

    SQL基础 1.DataBase 创建:CREATE DATABASE DATABASE_NAME ; 使用:USE DATABASE_NAME ; 删除:DROP DATABASE DATABASE ...

  8. java sql分析器_java sql解析器比较druid sql parser vs jsqlparser vs fdb-sql-parser

    先上结论. 功能上:druid sql parser(支持分区.WITH.DUAL等.使用mysql语法解析时,已知oracle的一些操作符会被转为mysql,如|| 转为OR.使用oracle解析器 ...

  9. java sql编码_java+sql 编码 UTF-8、ISO-8859-1、GBK

    java 编码 UTF-8.ISO-8859-1.GBK Java支持UTF-8.ISO-8859-1.GBK等各种字体编码,可笔者发现Java中字体编码的问题仍难倒了不少程序员,网上虽然也有不少关于 ...

最新文章

  1. 自行车车把会吧车刮坏吗_花10分钟即可开始使用车把
  2. iOS开发-自己定义重用机制给ScrollerView加入子视图
  3. github建站之路
  4. mysql使用shell脚本部署_shell脚本部署mysql主从
  5. cc、gcc、g++ 的区别和联系
  6. linux 内存一直在增加,linux – 缓存内存和共享内存总和超过总内...
  7. 前端Ajax/JS/HTML+后端SpringMVC(二)
  8. BAT技术大牛推荐:看懂英文文档,每天只需要10分钟做这件事……
  9. android屏幕基础知识
  10. vim 复制一行并且粘贴_Vim常用命令2之文本操作
  11. Web前端笔记-通过Thymeleaf把数组传输给echarts并显示曲线图
  12. 小型ASP服务器|简洁asp服务器
  13. win2003 程序时间提供程序 NtpClient错误解决
  14. httpd-2.4.18源码安装
  15. 黑苹果hd3000显存3m_加装黑苹果生产力翻倍,E3 神机规模升级再战五年
  16. 致虚极,守静笃【转】
  17. Oracle验证身份证号码有效性
  18. VBA学习笔记之Range.Resize属性
  19. OSChina 周六乱弹 ——揭秘后羿怎么死的
  20. IDEA创建项目时弹出链接超时的提示,亲测好用的解决办法

热门文章

  1. 纪念第一次ak。。。
  2. 《分布式虚拟现实系统(DVR)》(Yanlz+Unity+SteamVR+分布式+DVR+人工智能+边缘计算+人机交互+云游戏+框架编程+立钻哥哥+)
  3. 如何在微信直接下载APP(iOS/Android)的解决方案
  4. Intel的ipp库(Integrated Performance Primitives)
  5. C# Dev利用TreeList设置菜单导航并双击节点打开模块窗体
  6. VPS一键测试脚本 / 自带结果导出
  7. [算法] 手绘家谱的流程思考
  8. win10豆沙绿护眼色
  9. 3w最简单led灯电路图_三种常用的LED驱动电源电路图详解
  10. 二级分销商城的宣传推广方法