jdbc原子事务的实现

在实际业务中,我们常常能够遇到一些需求,这个需求中有数个操作,要所有操作都成功完成了这个需求才实现了,这就是原子性事务。比如说,银行交易,转账过程包括转账者钱的数量扣除和接受者钱的数量增加,要同时完成才能算转账成功,不允许只完成一部分。

jdbc实现原子事务的过程主要是通过手动控制提交(commit)来实现的,在一次提交过程中将所有需要的操作都准备好,然后一次性提交到数据库中,如果中间某一个过程执行失败,则会进行回滚操作,防止部分更新,以下面的代码为例,代码是实现报表的定制,需要往两个表中插入数据才算定制成功,往这两个表中插入数据算一个原子事务,代码如下:

/*
* 通过传入的TableItem参数来保存报表,返回保存的报表条目的主键值
* 报表插入过程应该为一个整体的事务,要么都成功,要么都失败
* params:
* 	value:报表需要的参数
* 	rowList:行列条件
* 	colList:列条件
* return:
* 	primaryKey:生成的主键值
*/
public int saveReportTable(TableItem value,List<TJItem> rowList,List<TJItem> colList){
	int primaryKey=0;
	String sql="insert into REPORTTABLE(TITLE";
	boolean hasSD=false;                                       //是否有起始日期
	boolean hasED=false;                                       //是否有终止日期
		
	if(value.getStartDate()!=null){
		hasSD=true;
		sql+=",STARTDATE";
	}
	if(value.getEndDate()!=null){
		hasED=true;
		sql+=",ENDDATE";
	}
		
	sql+=",STARTTIME";                                         //不管是否是空,都插入,判断在后面
	sql+=",ENDTIME";                                           
		
	sql+=") VALUES(?";
		
	if(hasSD)
		sql+=",?";
	if(hasED)
		sql+=",?";
		
	sql+=",?";
	sql+=",?";
	sql+=")";
	logger.info("保存报表构造的sql为:"+sql);
		
	//插入行列条件的sql
      String tjSql="insert into REPORTTJ(TABLE_ID,ROWORCOL,TABLE_NAME,TABLE_SK,TJVALUE,TJNAME) VALUES(?,?,?,?,?,?)";
	logger.info("插入行列条件的sql为:");
		
	try {
		con.setAutoCommit(false);                                      //取消自动提交,改为手动提交
			
		//保存报表sql过程
		String generatedColumns[] = { "TABLE_ID" }; 
		pres=con.prepareStatement(sql,generatedColumns);
			
		int num=1;
		pres.setString(num, value.getTableTitle());
		num++;
		if(hasSD){
			pres.setDate(num, value.getStartDate());
			num++;
		}
		if(hasED){
			pres.setDate(num, value.getEndDate());
			num++;
		}
			
		pres.setInt(num, value.getStartTime());
		num++;
			
		pres.setInt(num, value.getEndTime());
		num++;
			
		pres.executeUpdate();                                           //插入到数据库
		ResultSet res=pres.getGeneratedKeys();                          //返回生成的主键
			
		while(res.next()){
			primaryKey=res.getInt(1);                                   //生成的主键
		}
			
			
		//保存行条件过程
		pres=con.prepareStatement(tjSql);
			
		TJItem tItem;
		for(int i=0;i<rowList.size();i++){
			tItem=rowList.get(i);
				
			pres.setInt(1, primaryKey);                                 //所属的报表的ID                              
			pres.setInt(2, tItem.getFlag());
			pres.setString(3, tItem.getTableName());
			pres.setString(4, tItem.getKeyName());
			pres.setString(5, tItem.getWhereStr());
			pres.setString(6, tItem.getWhereName());
				
			pres.addBatch();                                           //为了批量处理
		}
			
		pres.executeBatch();                                              //实现批量插入
			
			
		//保存列条件过程
		pres=con.prepareStatement(tjSql);
			
		for(int i=0;i<colList.size();i++){
			tItem=colList.get(i);
				
			pres.setInt(1, primaryKey);                                //所属的报表的ID                              
			pres.setInt(2, tItem.getFlag());
			pres.setString(3, tItem.getTableName());
			pres.setString(4, tItem.getKeyName());
			pres.setString(5, tItem.getWhereStr());
			pres.setString(6, tItem.getWhereName());
				
			pres.addBatch();                                          //为了批量处理
		}
			
		pres.executeBatch();                                              //实现批量插入
			
		con.commit();                                                     //提交所有事务
			
		if(res!=null)
			res.close();
		if(pres!=null)
			pres.close();
			
		con.setAutoCommit(true);                                          //打开自动提交过程
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		
	return primaryKey;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值