JDBC事务处理


一、JDBC事务

(1)事务是作为单个逻辑工作单元执行的一系列操作。
(2)事务维护了数据的完整性、正确语义、持久性。事务中的所有SQL语句必须被成功执行,则事务才会对数据库产生持久性的影响,
如果事务中的第n条语句执行出错,表示事务运行失败,则前面的n-1条语句对数据库产生的影响可以撤销(回滚)到事务执行前的初
始状态或出错点之前的某个正确状态。 
(3)JDBC在默认情况下,使用事务自动提交模式,它将接收到的每一条SQL操作当作一个事务提交给数据库服务器处理。
如果要启动手动事务模式,程序的基本结构如下:



二.JDBC事务回滚方式

JDBC事务回滚主要有两种方式:
(1)一种是回滚所有事务,恢复到事务的初始状态,直接调用Connection中的rollback()方法实现。 
(2)另一种是回滚部分事务,要事先要定义保存点,发生异常时回滚到指定的保存点处。定义保存点的方法如下:
Savepoint save3 = con.setSavepoint(); 

三.实例分析

(1)用JDBC的手动事务处理给pubs数据库的authors作者表添加两条新记录,第一条记录的信息是正确的,第二条记录的作者编号是错误的,
分别用回滚全部事务和回滚部分事务处理异常。操作步骤如下:
第一种:回滚全部事务。

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*"  errorPage="" %>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
</head>

<body>
<%
   	Connection	         con=null;
    PreparedStatement     st =null;
	try
	{
      Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
	  String url="jdbc:sqlserver://localhost:1433;databaseName=pubs;user=sa;password=";
	  con = DriverManager.getConnection(url);   
	  
	  String sql="insert into authors (au_id,au_lname,au_fname,phone,contract) values (?,?,?,?,?)";
	  st=con.prepareStatement(sql);
	 
	  con.setAutoCommit(false);  //关闭JDBC的自动失误提交功能

	  st.setString(1,"333-33-4455");
	  st.setString(2,"Tomcat");
	  st.setString(3,"Apache");
	  st.setString(4,"111 222-3333");
	  st.setInt(5,1);
	  st.executeUpdate();
	  
	  st.setString(1,"2A2-33-4455");
	  st.setString(2,"Rose");
	  st.setString(3,"Bill");
	  st.setString(4,"333 222-3333");
	  st.setInt(5,1);
	  st.executeUpdate();
	  
	  con.commit();  //提交事务
	  out.println("成功加入记录,请用查询分析器验证");
	}
  catch(Exception e)
  {
     out.println("出错:"+e);
	 out.println("<br>回滚全部事务");
	 con.rollback();  //回滚所有的事务
  }
  finally
  { 
    
	if(st != null )
	   {st.close();}
	if(con != null )
	   {
	      con.setAutoCommit(true);
	      con.close();
		}
  }	
%>
</body>
</html>

第二种:回滚部分事务。

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*"  errorPage="" %>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
</head>
<%@page import="javax.sql.*"%>
<body>
<%
   	Connection	         con=null;
    PreparedStatement     st =null;
	int counter=0;  //定义一个计数器 用于识别应该会滚到哪一个保存点
	Savepoint p=null,p0=null,p1=null;
	try
	{
      Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
	  String url="jdbc:sqlserver://localhost:1433;databaseName=pubs;user=sa;password=";
	  con = DriverManager.getConnection(url);   
	  
	  String sql="insert into authors (au_id,au_lname,au_fname,phone,contract) values (?,?,?,?,?)";
	  st=con.prepareStatement(sql);
	 
	  con.setAutoCommit(false);
      
	  p0=con.setSavepoint("1");  //保存断点
	  counter=1;  //将断点标记为1
	  
	  st.setString(1,"333-33-4455");
	  st.setString(2,"Tomcat");
	  st.setString(3,"Apache");
	  st.setString(4,"111 222-3333");
	  st.setInt(5,1);
	  st.executeUpdate();
	 
	  p1=con.setSavepoint("2");
	  counter=2;
	 
	  st.setString(1,"2A2-33-4455");
	  st.setString(2,"Rose");
	  st.setString(3,"Bill");
	  st.setString(4,"333 222-3333");
	  st.setInt(5,1);
	  st.executeUpdate();
	  
	  con.commit(); 
	  out.println("成功加入记录,请用查询分析器验证");
	}
  catch(SQLException e)
  {
     out.println("出错:"+e);
	 out.println("<br>回滚部分事务,请用查询分析器验证");
	 
	 switch(counter)  //根据标示识别断点
	 {
	    case 1: 
		        con.rollback(p0);
		        break;
	    case 2: con.rollback(p1);
		        break;
		default:con.rollback();
	 }
  }
  finally
  { 
    
	if(st != null )
	   {st.close();}
	if(con != null )
	   {
	      con.setAutoCommit(true);
	      con.close();
		}
  }	
%>
</body>
</html>








郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。