最近做了一个springMVC+mybatis的项目,项目开发过程中比较顺利,我使用的主要jar包如下列表:
其中基础配置有个:一个是关于数据库的,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:resources/prop/spring-jdbc.properties</value>
</list>
</property>
</bean>
<!--
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="maxWait" value="${jdbc.maxWait}" />
<property name="poolPreparedStatements" value="true" />
<property name="testWhileIdle" value="true"/>
<property name="validationQuery" value="select 1 from dual"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:resources/mybatis/SqlMapConfig.xml"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 由spring管理mybatis的事物 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 定义拦截器,用来指定事物属性,级别,和异常处理 -->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<!--
PROPAGATION_SUPPORTS: 如果已经存在事务,则加入事务;如果没有事务,则以非事务的方式执行;
PROPAGATION_MANDATORY: 使用当前事务, 如果没有, 则抛出异常;
PROPAGATION_REQUIRED: 新建事务,如果当前有事务, 则挂起;
PROPAGATION_NOT_SUPPORTED:以非事务的方式执行, 如果当前有事务, 则挂起;
PROPAGATION_NEVER:以非事务的方式执行, 如果当前有事务,则抛出异常;
+/-Exception</prop> + 表示异常出现时事物提交 - 表示异常出现时事务回滚 -->
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="select*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="del*"> PROPAGATION_REQUIRED,-BusinessException</prop>
<prop key="delete*"> PROPAGATION_REQUIRED,-BusinessException</prop>
<prop key="update*">PROPAGATION_REQUIRED,-BusinessException</prop>
<prop key="save*">PROPAGATION_REQUIRED,-BusinessException</prop>
<prop key="add*">PROPAGATION_REQUIRED,-BusinessException</prop>
</props>
</property>
</bean>
<!-- 用来定义那些类需要采用事物管理 spring 事物的动态代理类 BeanNameAutoProxyCreator 根据类名自动代理,接受表达式 -->
<bean id="BeanProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<!-- 对类名以Service结尾的类进行代理 -->
<value>*Service*</value>
</property>
<!-- 对代理类进行加载拦截器(实现通知的过程) -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
</beans>
一个是关于spring MVC的,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="cn.***.controller" />
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<mvc:annotation-driven />
<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp" p:viewClass="org.springframework.web.servlet.view.JstlView"/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" scope="prototype">
<!-- 最大5m 1024 * 1024 * 5 * 6 -->
<property name="maxUploadSize" value="31457280"/>
<property name="maxInMemorySize" value="4096"/>
<property name="resolveLazily" value="true"/>
</bean>
</beans>
通过压力测试还算顺利,但是当接入生产环境时候有了许多问题,其中问题在于与生产中许多外围环境的接入,问题有:
1、单点登陆在集群环境下的退出问题;
当单机访问单点登陆服务器时,系统运行正常可是当我们的服务器是负载方式的时候系统就不能退出,问题就在于与负载有多台机器,当单点服务器返回注销消息时负载会随便发送给一台机器处理,当这台机器正好是之前的机器注销成功,如果不是则失败——现在的做饭是建失败的转发给其他机器继续处理,直到有成功的。
2、系统启动后一段时间后不能再登陆,从系统后台日志可以看出是系统在从数据源中获取连接时一直处于等待状态,如果是数据连接不能获取的话它会在一段时间之后会超时报错,但是经过反复测试未出现超时情况;疑点有两个:一是在未接入单点登陆的时候系统未出现过这种问题;二是当数据库连接池变更为jdbc连接时不会出现问题。如果有哪位高手遇到过此问题,希望不吝赐教!
本人估计是线程死锁,还在研究中。
3、系统使用的数据源是DBCP,问题二发生以后我们猜想是数据库连接池的问题,有意将其修改为c3p0,但是将其修改为c3p0时却出现了如下错误:
2014-09-24 20:07:04,276-[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0][DEBUG]-[BasicResourcePool]An exception occurred while acquiring a poolable resource. Will retry.
java.sql.SQLException: invalid arguments in call
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
c3p0配置如下:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="jdbcUrl"><value>${racURL}</value></property>
<property name="user"><value>${username}</value></property>
<property name="password"><value>${password}</value></property>
<!-- 连接池中保留的最小连接数 -->
<property name="minPoolSize"><value>5</value></property>
<!-- 连接池中保留的最大连接数 -->
<property name="maxPoolSize"><value>10</value></property>
<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime"><value>1800</value></property>
<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 -->
<property name="acquireIncrement"><value>5</value></property>
<!-- 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭,maxStatementsPerConnection默认为0 -->
<property name="maxStatements"><value>0</value></property>
<!-- 初始连接池大小 -->
<property name="initialPoolSize"><value>5</value></property>
<!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod"><value>0</value></property>
<!-- 定义在从数据库获取新连接失败后重复尝试的次数 -->
<property name="acquireRetryAttempts"><value>3</value></property>
<!-- 获取连接失败后该数据源将申明已断开并永久关闭 -->
<property name="breakAfterAcquireFailure"><value>false</value></property>
<!-- 方法来提升连接测试的性能 -->
<property name="testConnectionOnCheckout"><value>false</value></property>
</bean>
有人说配置的问题,但是我的配置曾经在生产环境中使用过,没有问题的到现在生产运行的相当稳定。