- 浏览: 53143 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (77)
- mybatis spring java ibatis 注解 (1)
- maven (4)
- myeclipse (5)
- eclipse (2)
- MyEclipse6.5 (4)
- SVN (2)
- tomcat (2)
- oracle,powerdesigner (2)
- oracle (6)
- Log4j (3)
- mybatis (3)
- 微信 (1)
- token (1)
- dom4j (3)
- xml (3)
- webservice (1)
- axis2 (1)
- java (3)
- jstl (1)
- springmvc (3)
- hibernate (1)
- jquery (5)
- jquery-validation (1)
- jetty (1)
- xshell (1)
- cookie (2)
- PL/SQL (1)
- linux操作系统学习 (1)
- 免费API (1)
- ajax (5)
- Ubuntu (1)
- 遍历Map的四种方法 (1)
最新评论
一次做应用升级出现了一个问题,描述如下:
升级分为两块,一块是数据库结构变更(表结构增加新字段);一块是应用程序的升级。
应用环境为: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 while applying 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)
... 33 more
Java代码 收藏代码
Caused by: com.alibaba.generalorm.dao.DataAccessException: Data query error!
--- The error occurred in sqlmap/CiaDissension.xml.
--- The error occurred while applying 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)
... 33 more
为什么会出现违反协议的问题?马上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代码 收藏代码
<local-tx-datasource>
<jndi-name>rccBopsDataSource</jndi-name>
<use-java-context>false</use-java-context>
<connection-url>jdbc:oracle:thin:@xx.xx.xx.xx:1521:xx</connection-url>
<connection-property name="SetBigStringTryClob">true</connection-property>
<connection-property name="defaultRowPrefetch">50</connection-property>
<connection-property name="clientEncoding">GBK</connection-property>
<connection-property name="serverEncoding">ISO-8859-1</connection-property>
<driver-class>com.alibaba.china.jdbc.SimpleDriver</driver-class>
<min-pool-size>1</min-pool-size>
<max-pool-size>14</max-pool-size>
<prepared-statement-cache-size>20</prepared-statement-cache-size>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
<idle-timeout-minutes>15</idle-timeout-minutes>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<user-name>xx</user-name>
<password>xx</password>
</local-tx-datasource>
其中prepared-statement-cache-size参数解释为:
<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代码 收藏代码
<bean id="testDataSource"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod">
<value>com.mchange.v2.c3p0.DataSources.pooledDataSource</value>
</property>
<property name="arguments">
<list>
<ref local="unpooledDataSource" />
<props>
<prop key="acquireIncrement">1</prop>
<prop key="initialPoolSize">1</prop>
<prop key="minPoolSize">1</prop>
<prop key="maxPoolSize">5</prop>
<prop key="maxIdleTime">1800</prop>
<prop key="maxIdleTimeExcessConnections">1000</prop>
<!-- 自动收缩连接用的,单位秒 -->
<!-- 自动重连需要的三个参数 -->
<prop key="acquireRetryAttempts">30</prop>
<prop key="acquireRetryDelay">1000</prop>
<prop key="breakAfterAcquireFailure">false</prop>
<!-- 获取一个connection需要的时间,单位毫秒 -->
<prop key="checkoutTimeout">5000</prop>
</props>
</list>
</property>
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的详细参数
升级分为两块,一块是数据库结构变更(表结构增加新字段);一块是应用程序的升级。
应用环境为: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 while applying 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)
... 33 more
Java代码 收藏代码
Caused by: com.alibaba.generalorm.dao.DataAccessException: Data query error!
--- The error occurred in sqlmap/CiaDissension.xml.
--- The error occurred while applying 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)
... 33 more
为什么会出现违反协议的问题?马上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代码 收藏代码
<local-tx-datasource>
<jndi-name>rccBopsDataSource</jndi-name>
<use-java-context>false</use-java-context>
<connection-url>jdbc:oracle:thin:@xx.xx.xx.xx:1521:xx</connection-url>
<connection-property name="SetBigStringTryClob">true</connection-property>
<connection-property name="defaultRowPrefetch">50</connection-property>
<connection-property name="clientEncoding">GBK</connection-property>
<connection-property name="serverEncoding">ISO-8859-1</connection-property>
<driver-class>com.alibaba.china.jdbc.SimpleDriver</driver-class>
<min-pool-size>1</min-pool-size>
<max-pool-size>14</max-pool-size>
<prepared-statement-cache-size>20</prepared-statement-cache-size>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
<idle-timeout-minutes>15</idle-timeout-minutes>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<user-name>xx</user-name>
<password>xx</password>
</local-tx-datasource>
其中prepared-statement-cache-size参数解释为:
<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代码 收藏代码
<bean id="testDataSource"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod">
<value>com.mchange.v2.c3p0.DataSources.pooledDataSource</value>
</property>
<property name="arguments">
<list>
<ref local="unpooledDataSource" />
<props>
<prop key="acquireIncrement">1</prop>
<prop key="initialPoolSize">1</prop>
<prop key="minPoolSize">1</prop>
<prop key="maxPoolSize">5</prop>
<prop key="maxIdleTime">1800</prop>
<prop key="maxIdleTimeExcessConnections">1000</prop>
<!-- 自动收缩连接用的,单位秒 -->
<!-- 自动重连需要的三个参数 -->
<prop key="acquireRetryAttempts">30</prop>
<prop key="acquireRetryDelay">1000</prop>
<prop key="breakAfterAcquireFailure">false</prop>
<!-- 获取一个connection需要的时间,单位毫秒 -->
<prop key="checkoutTimeout">5000</prop>
</props>
</list>
</property>
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的详细参数
发表评论
-
oracle创建表空间( 转)
2014-04-19 16:51 497注意点: 1.如果在PL/SQL 等工具里打开的话,直接修改 ... -
oracle 数据类型详解---日期型(转载)
2014-03-31 15:02 693oracle 数据类型详解---日期型 orac ... -
Oracle计算时间函数(numtodsinterval、numtoyminterval)及其应用
2014-03-31 15:00 1920numtodsinterval(<x>,<c ... -
Oracle新建用户、角色,授权,建表空间
2014-03-25 14:17 258oracle数据库的权限系统 ... -
Oracle10g中用浏览器登陆isql*plus dba
2014-03-24 11:40 396登陆isqlplus dba: http://ip:5560/ ...
相关推荐
- 一个表空间可以包含一个或多个数据文件。 - 一个数据文件只能属于一个表空间。 - **应用场景**:用于存储用户数据、索引等信息。 **2. 日志文件** - **重做日志文件** - **定义**:记录数据库更改的日志文件...
连续两个双引号转义为一个双引号 定界标识符的例子: 保留字的清单参见附录 语言的功能及语句 语言是一种介于关系代数与关系演算之间的语言,其功能主要包括数据定义、查询 操纵和控制四个方面,通过各种不同的...
3. **多图斑内单起变更**:涉及不同图斑之间的合并或分割,例如新开垦的土地位于两块不同类型的土地之间。 4. **多图斑内多起变更**:在多个图斑内发生复杂的变更情况,如新建一条公路导致多块不同类型的土地被占用...
1. **表空间**:表空间是Oracle数据库的一个逻辑存储单元,一个数据库可以包含一个或多个表空间。每个表空间对应一个或多个物理数据文件。表空间主要用于: - 控制数据库对象如表、索引等的空间分配。 - 设置用户...
它可能包括一个`SQLiteOpenHelper`子类,定义了数据库版本和表结构,以及创建和升级数据库的方法。此外,还有可能展示了如何执行SQL命令,进行数据查询和管理`Cursor`的方法。 通过学习这个入门级的demo,你应该...
- 表空间是Oracle数据库的逻辑存储单元,每个表空间由一个或多个数据文件组成。 - 默认情况下,Oracle数据库会创建名为`SYSTEM`和`SYSAUX`的表空间。 **表空间的管理:** - 可以通过SQL语句创建、删除、修改表空间...
表是存储数据的基本结构,视图是基于表的查询结果集,存储过程是一组为了完成特定功能的SQL语句集,函数类似于存储过程,但必须返回一个值,触发器是数据库表中发生特定事件时自动执行的代码块。 ### 系统表的整理 ...
- **检查最近的数据库变更记录**:如硬件、软件的升级或配置更改等。 - **分析相关日志信息**:操作系统日志、数据库alert log信息、AWR报告等都是重要的线索来源。 - **按需进行系统切换**:如果必要,按照预设的...
- **实时应用集群(Real Application Clusters)**: 允许多个Oracle实例访问同一个数据库,提高可用性和性能。 - **Oracle Enterprise Manager工具包**: 提供了一系列工具,帮助DBA进行高级诊断、监视、优化和管理...
数据块是最小的存储单位,多个数据块构成一个区,多个区又组成一个段,而段最终归属于特定的表空间。这一层次化的存储结构不仅优化了数据访问速度,还简化了数据库的管理和维护。 #### Oracle实例的后台进程功能 ...
Oracle数据库的内存结构主要分为两个部分:系统全局区(System Global Area, SGA)和程序全局区(Program Global Area, PGA)。 - **Java Pool**:用于存储Java应用程序的数据和代码。 - **Database Buffer Cache**...
集成测试:一个应用系统的各个部件的联合测试,以决定他们能否在一起共同工作。部件可以是代码块、独立的应用、网络上的客户端或服务器端程序。这种类型的测试尤其与客户服务器和分布式系统有关。 功能测试:...
表空间是数据库中最大的逻辑存储单元,一个表空间可以包含多个数据文件;段则是表空间内的逻辑存储区域,用于存放特定类型的数据(如表、索引);区间则是数据文件中分配给段的具体存储区域。 - **1.1.5 模式和通用...
Oracle数据库是世界上最流行的数据库管理系统之一,其强大的功能和复杂性源于其精细的体系结构。本讲将深入探讨Oracle体系结构的几个关键方面:物理结构、逻辑结构、内存结构、数据库实例与进程,以及数据字典。 ...
- **数据库主页**:是Oracle Enterprise Manager的一个页面,显示关于数据库的重要信息和状态。 - **使用SQL*Plus 和iSQL*Plus 访问数据库**:SQL*Plus是最常用的命令行工具之一,而iSQL*Plus则是基于Web的SQL执行...