从spring管理的datasource获取connection实例
2017-09-15 11:42
169 查看
1.在spring-db.xml下:
<bean id="payDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${pay.jdbc.url}" />
<property name="username" value="${pay.jdbc.username}" />
<property name="password" value="${pay.jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="maxActive" value="${pay.jdbc.maxActive}" />
<property name="initialSize" value="${pay.jdbc.initialSize}" />
<property name="minIdle" value="${pay.jdbc.minIdle}" />
<!-- maxWait 获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- timeBetweenEvictionRunsMillis间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- minEvictableIdleTimeMillis 一个连接在池中最小空闲的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'z'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="filters" value="stat" />
</bean>
2.在具体的服务类注入数据源的属性
<!-- 业务交易流水序列号产生服务 -->
<bean id="txnSeqNoService" class="com.cgd.pay.atom.impl.SequenceNoServiceImpl" init-method="init">
<property name="dataSource" ref="payDataSource" />
<property name="seqName" value="BI_TXN"/>
</bean>
3.在具体的操作方法中
import
javax.sql.DataSource;
import ......
public class SequenceNoServiceImpl implements SequenceNoService {
public long generateSeqNo() {
long result=-1;
String fail="";
synchronized(this) {
if( seqNo>bufMaxSeqNo ) { //系统重启后或buf耗完
for(int i=0;i<3;i++) { //尝试3次
Connection conn=getConn();
if( conn!=null ) {
try {
result=selectNewSeqNo(conn); //reuslt=查到的首个可用序号
if( result==-1 ) {
fail=",无法获取有效的序号";
logger.warn("第"+(i+1)+"次尝试产生序列号"+seqName+"失败,"+fail);
}
else break; //成功产生序号
}catch (SQLException e1) {
e1.printStackTrace();
if(con!=null){
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}finally {
this.closeConnection(conn);
关闭数据库连接
}
}else {
fail=",获取数据库连接失败";
logger.warn("第"+(i+1)+"次尝试产生序列号"+seqName+"失败,"+fail);
}
}
}else {
result=seqNo;
}
seqNo+=incStep; //自动增长
}
if( result==-1 )
throw new BusinessException("RSP_CODE_ATOM_SERVICE_ERROR","产生序列号失败"+fail);
return result;
}
protected Connection getConn() {
Connection connection=null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
设置为手动提交,保持数据的完整性一个系统的更新操作可能要涉及多张表,需多个SQL语句进行操作循环里连续的进行插入操作,
如果你在开始时设置了:conn.setAutoCommit(false);
最后才进行conn.commit(),这样你即使插入的时候报错,
修改的内容也不会提交到数据库,而如果你没有手动的进行setAutoCommit(false);出错时就会造成,前几条插入,后几条没有会
形成脏数据~~
设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁
} catch (SQLException e) {
e.printStackTrace();
logger.error("Sequence Service get connection failed:"+e.getMessage(),e);
}
return connection;
}
protected void closeConnection(Connection conn) {
closeConnection(conn,false);
}
protected void closeConnection(Connection conn,boolean rollBack) {
%try {
if( rollBack ) conn.rollback();
else conn.commit();
} catch (SQLException e1) {
e1.printStackTrace();
logger.error("Sequence
Service commit/rollback("+rollBack+") failed:"+e1.getMessage(),e1);
}%
try {
conn.close();
} catch (SQLException e) {
//e.printStackTrace();
}
}
}
<bean id="payDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${pay.jdbc.url}" />
<property name="username" value="${pay.jdbc.username}" />
<property name="password" value="${pay.jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="maxActive" value="${pay.jdbc.maxActive}" />
<property name="initialSize" value="${pay.jdbc.initialSize}" />
<property name="minIdle" value="${pay.jdbc.minIdle}" />
<!-- maxWait 获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- timeBetweenEvictionRunsMillis间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- minEvictableIdleTimeMillis 一个连接在池中最小空闲的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'z'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="filters" value="stat" />
</bean>
2.在具体的服务类注入数据源的属性
<!-- 业务交易流水序列号产生服务 -->
<bean id="txnSeqNoService" class="com.cgd.pay.atom.impl.SequenceNoServiceImpl" init-method="init">
<property name="dataSource" ref="payDataSource" />
<property name="seqName" value="BI_TXN"/>
</bean>
3.在具体的操作方法中
import
javax.sql.DataSource;
import ......
public class SequenceNoServiceImpl implements SequenceNoService {
public long generateSeqNo() {
long result=-1;
String fail="";
synchronized(this) {
if( seqNo>bufMaxSeqNo ) { //系统重启后或buf耗完
for(int i=0;i<3;i++) { //尝试3次
Connection conn=getConn();
if( conn!=null ) {
try {
result=selectNewSeqNo(conn); //reuslt=查到的首个可用序号
if( result==-1 ) {
fail=",无法获取有效的序号";
logger.warn("第"+(i+1)+"次尝试产生序列号"+seqName+"失败,"+fail);
}
else break; //成功产生序号
}catch (SQLException e1) {
e1.printStackTrace();
if(con!=null){
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}finally {
this.closeConnection(conn);
关闭数据库连接
}
}else {
fail=",获取数据库连接失败";
logger.warn("第"+(i+1)+"次尝试产生序列号"+seqName+"失败,"+fail);
}
}
}else {
result=seqNo;
}
seqNo+=incStep; //自动增长
}
if( result==-1 )
throw new BusinessException("RSP_CODE_ATOM_SERVICE_ERROR","产生序列号失败"+fail);
return result;
}
protected Connection getConn() {
Connection connection=null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
设置为手动提交,保持数据的完整性一个系统的更新操作可能要涉及多张表,需多个SQL语句进行操作循环里连续的进行插入操作,
如果你在开始时设置了:conn.setAutoCommit(false);
最后才进行conn.commit(),这样你即使插入的时候报错,
修改的内容也不会提交到数据库,而如果你没有手动的进行setAutoCommit(false);出错时就会造成,前几条插入,后几条没有会
形成脏数据~~
设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁
} catch (SQLException e) {
e.printStackTrace();
logger.error("Sequence Service get connection failed:"+e.getMessage(),e);
}
return connection;
}
protected void closeConnection(Connection conn) {
closeConnection(conn,false);
}
protected void closeConnection(Connection conn,boolean rollBack) {
%try {
if( rollBack ) conn.rollback();
else conn.commit();
} catch (SQLException e1) {
e1.printStackTrace();
logger.error("Sequence
Service commit/rollback("+rollBack+") failed:"+e1.getMessage(),e1);
}%
try {
conn.close();
} catch (SQLException e) {
//e.printStackTrace();
}
}
}
相关文章推荐
- spring 结合 redis 正确从jedisConnectionFactory获取Jedis实例
- 在完全由Spring管理的环境中使用Spring的Context获取Bean实例
- 获取Spring管理的对象实例
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- 基于Eclipse的Spring4.3.3配置获取DataSource详解
- spring容器获取DataSource对象,进行简单数据库应用
- spring在非容器管理的类里获取bean
- SpringTest框架JUnit单元测试用例获取ApplicationContext实例的方法
- spring获取bean实例
- SpringTest框架JUnit单元测试用例获取ApplicationContext实例的方法
- spring 从bean实例中获取对象
- S2SH框架中,Spring通过注解获取bean实例
- 获取Spring IOC容器代理的Bean实例的几种方式
- Spring3.1.0实现原理分析(二十二).Dao事务分析之事务管理器DataSourceTransactionManager
- spring-项目启动下获取Bean实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- 由Spring管理的Struts2的Action的单实例问题
- 由Spring管理的Struts2的Action的单实例问题
- Android之HttpURLConnection应用实例:武大教务系统获取课表
- Spring datasource connection manager with jmx to expose real time connections count