您的位置:首页 > 编程语言 > Java开发

从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();
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息