Spring的JDBC事务实现

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

1、首先,让咱们来看看什么是事务java

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


事务主要用于处理操做量大,复杂度高的数据
一、在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
二、事务处理能够用来维护数据库的完整性,保证成批的SQL语句要么所有执行,要么所有不执行
三、事务用来管理insert,update,delete语句

事务具备如下特性:sql

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

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

三、隔离性(Isolation):一个事务的执行不能被其余事务所影响。服务器

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


事务可分为如下几种:app

一、自动提交事务框架

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

二、显式事务

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

三、隐式事务

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

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

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

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

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

务模式关闭为止。


2、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等。


3、事务应用实例

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

一、那么如何使用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()方法进行回滚。 

二、话很少说,直接上实现代码

 
/** * 数据提交 * @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(); } } }