Spring的JDBC事务实现

之前项目中有大量数据提交的需求,考虑了几个解决方案后还是觉得使用事务提交效率更高、数据插入也更方便。

一、首先,让我们来看看什么是事务

事务(Transaction)是并发控制的单元,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,sql server能将逻辑逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。事务通常由begin transaction开始,以Commit或者Rollback结束。Commit表示提交,即提交事务的所有操作,具体的说就是将事务中所有对数据的更新写回到数据库的物理磁盘上,事务正常结束。Rollback表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库 的所有已完成的操作全部撤销,滚回到事务开始的状态。


事务主要用于处理操作量大,复杂度高的数据
1、在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
2、事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行
3、事务用来管理insert,update,delete语句

事务具有以下特性:

1、原子性(Atomicity):事务是数据库的逻辑工作单元,必须是原子工作单位,事务的原子性确保动作要么全部执行,要么全部不执行。

2、一致性(Consistency):事务在完成时,系统必须确保所有的数据处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。

3、隔离性(Isolation):一个事务的执行不能被其他事务所影响。

4、持久性(Durability):一个事务一旦提交,事务的操作便永久的保存在DB中,即使此时再执行回滚操作也不能撤销所做的更改。无论发生什么系统错误,它的结果都不应该受到影响。


事务可分为以下几种:

1、自动提交事务

每条单独的语句都是一个事务。每个语句后都隐含一个commit。

2、显式事务

begin transaction开始,以Commit或者Rollback结束。

3、隐式事务

当连接以隐式事务模式进行操作时,sql server数据库引擎实例将在提交或回滚当前事务后自动启动新事务,无需描述事务的

开始,只需提交或回滚每个事务,但每个事务仍以Commit或者Rollback显式结束。连接将隐式事务模式打开后,为数据库引擎实例

首次执行以下任何语句时,都会自动启动一个隐式事务:alter table,insert,create,open,delete,revoke,drop,select,

fetch,truncate table,grant,update。在发出commit或rollback语句之前,该事务将一直保持有效。在第一个事务被提交或回

滚之后,下次当连接执行以上任何语句时,数据库引擎实例都会自动启动一个新事务。该引擎将不断生成隐式事务链,直到隐式事

务模式关闭为止。


二、Spring对事务的支持

Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。 Spring事务管理器的接口org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。

此接口的内容如下:

Public interface PlatformTransactionManager()...{  
    // 由TransactionDefinition得到TransactionStatus对象
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; 
    // 提交
    Void commit(TransactionStatus status) throws TransactionException;  
    // 回滚
    Void rollback(TransactionStatus status) throws TransactionException;  
    } 

从这里我们可以看到具体的事务管理机制对Spring来说是透明的,它并不关心那些,那些是对应各个平台需要关心的,所以Spring事务管理的一个优点就是为不同的事务API提供一致的编程模型,如JTA、JDBC、Hibernate、JPA等。


三、事务应用实例

本实例主要解决了提交大量数据的需求,使用JDBC事务实现。

1、那么如何使用JDBC事务呢?

如果应用程序中直接使用JDBC来进行持久化,DataSourceTransactionManager会来处理事务边界。为了使用DataSourceTransactionManager,我们需要使用如下的XML将其装配到应用程序的上下文定义中:

<!-- (事务管理)transaction manager-->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>


实际上,DataSourceTransactionManager是通过调用java.sql.Connection来管理事务,而后者是通过DataSource获取到的。通过调用连接的commit()方法来提交事务,同样,事务失败则通过调用rollback()方法进行回滚。

2、话不多说,直接上实现代码

/**
 * 数据提交
 * @return
 */
@RequestMapping(value = "/submitTerm.go", method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public void submitTerm(@RequestBody submitInfo submitInfo, HttpServletRequest request) throws Exception {

	//获取数据库连接
	WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
	DataSource dataSource = wac.getBean(DataSource.class);
	Connection con = dataSource.getConnection();
	PreparedStatement ps = null;

	try {
		 //设置事务的提交方式为非自动提交:
		 con.setAutoCommit(false);
		  // 创建执行语句
		String sql = "insert into dec_company_baseinfo (dwmc,addr,zzjgdm,yyzzzch,reg_time,postcode,"
				+ "e_mail,dw_url,jyfs,jyfw,dwzycp,hylb,hwyxjgs,qnydl,szzqjysc,gpdm,dkzhm,dwdjzclx,"
				+ "dwgsdjzh,dwdsdjzh,dwdh,dw_fax,zcszbsc,ssgxjsly,hwyfjgs,qnysl,gssssj,gfgsclfs,zczb,"
				+ "zczb_zz,zczb_wz,zczb_wzzb,sszb,sszb_zz,sszb_wz,sszb_wzzb,yfbgmj_lhn,yfbgmj_lhw,"
				+ "scyfmj_lhn,scyfmj_lhw,yyyfjg_country,yyyfjg_province,yyyfjg_city,yyyfjg_area,dwzz,"
				+ "dwzyzz,dwjbkhyh,khhm,yhxydj,yhzh,data_status,xzgl_num,scyx_num,yfsj_numjgzz_num,"
				+ "qtgw_num,bs_num,ss_num,bk_num,dz_num,qtxl_num,gjzc_num,zjzc_num,cjzc_num,qtzc_num,"
				+ "wjys_num,gdzjjhrc_num,lhxqgccrc_num,gjqrjhrc_num,szskqjhrc_num,gdcxcytd_num,"
				+ "szsgcczyrc_num,qtrc_num,snnmcyry_num,mzg_num,wzg_num,cjsb_num,lxgg_num,wjzj_num,"
				+ "snxzgxbys_num,sncpxssr,sndjlr,sndnsze,zzsze) values (#{dwmc},#{addr},#{zzjgdm},"
				+ "#{yyzzzch},#{reg_time},#{postcode},#{e_mail},#{dw_url},#{jyfs},#{jyfw},#{dwzycp},"
				+ "#{hylb},#{hwyxjgs},#{qnydl},#{szzqjysc},#{gpdm},#{dkzhm},#{dwdjzclx},#{dwgsdjzh},"
				+ "#{dwdsdjzh},#{dwdh},#{dw_fax},#{zcszbsc},#{ssgxjsly},#{hwyfjgs},#{qnysl},#{gssssj},"
				+ "#{gfgsclfs},#{zczb},#{zczb_zz},#{zczb_wz},#{zczb_wzzb},#{sszb},#{sszb_zz},"
				+ "#{sszb_wz},#{sszb_wzzb},#{yfbgmj_lhn},#{yfbgmj_lhw},#{scyfmj_lhn},#{scyfmj_lhw},"
				+ "#{yyyfjg_country},#{yyyfjg_province},#{yyyfjg_city},#{yyyfjg_area},#{dwzz},"
				+ "#{dwzyzz},#{dwjbkhyh},#{khhm},#{yhxydj},#{yhzh},#{data_status},#{xzgl_num},"
				+ "#{scyx_num},#{yfsj_numjgzz_num},#{qtgw_num},#{bs_num},#{ss_num},#{bk_num},#{dz_num},"
				+ "#{qtxl_num},#{gjzc_num},#{zjzc_num},#{cjzc_num},#{qtzc_num},#{wjys_num},"
				+ "#{gdzjjhrc_num},#{lhxqgccrc_num},#{gjqrjhrc_num},#{szskqjhrc_num},#{gdcxcytd_num},"
				+ "#{szsgcczyrc_num},#{qtrc_num},#{snnmcyry_num},#{mzg_num},#{wzg_num},#{cjsb_num},"
				+ "#{lxgg_num},#{wjzj_num},#{snxzgxbys_num},#{sncpxssr},#{sndjlr},#{sndnsze},#{zzsze})";

		String sql1 = "insert into dec_talent_baseinfo (zzjgdm,rc_type,name,xl,mobile,tel,fax,e_mail,"
				+ "card_type,card_no,zw,zc) values (#{zzjgdm},#{rc_type},#{name},#{xl},#{mobile},"
				+ "#{tel},#{fax},#{e_mail},#{card_type},#{card_no},#{zw},#{zc})";

		String sql2 = "insert into dec_finance_baseinfo (zzjgdm,xmlb,sn,qn,dqn,zzl_avg) values "
				+ "(#{zzjgdm},#{xmlb},#{sn},#{qn},#{dqn},#{zzl_avg})";

		String sql3 = "insert into dec_development_baseinfo (zzjgdm,xmmc,sn,qn,dqn,data_status,zzl_avg)"
				+ " values (#{zzjgdm},#{xmmc},#{sn},#{qn},#{dqn},#{data_status},#{zzl_avg})";

		String sql4 = "insert into dec_support_baseinfo (zzjgdm,seq,xmmc,zzbm,zzje,zzxs,zzsj,yssj,"
				+ "xmysqk,jkchqk,hksj) values (#{zzjgdm},#{seq},#{xmmc},#{zzbm},#{zzje},#{zzxs},"
				+ "#{zzsj},#{yssj},#{xmysqk},#{jkchqk},#{hksj})";

		String sql5 = "insert into dec_products_baseinfo (zzjgdm,seq,zycpmc,sfjyzscq,cplx,cpxxsrze,"
				+ "zqyxssrbl) values (#{zzjgdm},#{seq},#{zycpmc},#{sfjyzscq},#{cplx},#{cpxxsrze},"
				+ "#{zqyxssrbl})";

		// 分别执行事务
		ps = con.prepareStatement(sql);
		ps.executeUpdate();
		ps = con.prepareStatement(sql1);
		ps.executeUpdate();
		ps = con.prepareStatement(sql2);
		ps.executeUpdate();
		ps = con.prepareStatement(sql3);
		ps.executeUpdate();
		ps = con.prepareStatement(sql4);
		ps.executeUpdate();
		ps = con.prepareStatement(sql5);
		ps.executeUpdate();
		// 在try块内添加事务的提交操作,表示操作无异常,提交事务。
		con.commit();
		con.setAutoCommit(true);
	} catch (Exception ex) {
		try {
			con.rollback();		//操作失败则事务回滚
		} catch (Exception e) {
			e.printStackTrace();
		}
		ex.printStackTrace();
	} finally {
		//最后一定要关闭
		try {
			ps.close();
			con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值