zoukankan      html  css  js  c++  java
  • JDBC中处理事务,小Demo

    事务的四大特性(ACID):

     

    原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。

    一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。

    隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。

    持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

          在默认情况下,每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。


    开启事务:start transaction;
     结束事务:commit或rollback。


          在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都被撤消了!


     

    Connection的三个方法与事务相关:

    (1) setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值就是true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务。

                 如果设置false,那么就相当于开启了事务了;con.setAutoCommit(false)表示开启事务。

    (2) commit():提交结束事务;con.commit();表示提交事务。

    (3) rollback():回滚结束事务。con.rollback();表示回滚事务。

    jdbc处理事务的代码格式:

    try {
      con.setAutoCommit(false);//开启事务…
      ….
      …
      con.commit();//try的最后提交事务
    } catch() {
      con.rollback();//回滚事务
    }
    


     

    首先做一些准备工作:

    (1)配置数据源,确定使用的数据库。详细信息见http://blog.csdn.net/qq_25827845/article/details/50836362

    (2)在数据库中建立表account,并且插入数据

    create table account
    (
      id int,
      balance int,
    )
    select * from account
    insert into account values (1,1000)
    insert into account values (2,1000)

    如图所示:

    在程序中,首先是程序没有发生异常,则,转账成功。

    当程序发生异常时,查询数据库,则会发现转账操作并没有完成。符合ACID特性。

    Demo代码展示:

    package com.ywq;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class Dao {
    	/**
    	 * 修改指定用户的余额!
    	 * @param ct
    	 * @param id
    	 * @param balance
    	 */
    	
    	//同一事务中必须使用同一个Connection对象,所以此处的Connection对象由调用处传入。
    	public void updateBalance(Connection ct,int id,int balance){
    		
    		
    		try {
    			String sql="update account set balance=balance+? where id=?";
    			PreparedStatement pt=ct.prepareStatement(sql);
    			
    			pt.setInt(1, balance);
    			pt.setInt(2, id);
    			
    			pt.executeUpdate();
    			
    		} catch (SQLException e) {
    			
    			throw new RuntimeException(e);
    		}
    		
    		
    	}
    
    }
    


     

    package com.ywq;
    
    import java.sql.*;
    
    public class Demo {
    
    	public static void main(String[] args) {
    		zhuanZhang(1, 2, 100);
    
    	}
    	
    	public static void zhuanZhang(int from, int to, int money) {
    		// 对事务的操作必须使用Connection对象!
    		Connection ct = null;
    		try {
    			 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");  
    			 ct=DriverManager.getConnection("jdbc:odbc:ywq");  
    			 System.out.println(ct);
    			
    			//开启事务
    			ct.setAutoCommit(false);
    
    			Dao dao = new Dao();
    			dao.updateBalance(ct, from, -money);//给from减去相应金额
    			
    			if(true) {
    //把此处的if语句块注释掉,则转账成功 	throw new RuntimeException("不好意思,此处发生了异常,但是转账操作进行了一半,请观察结果");
    			}
    			
    			dao.updateBalance(ct, to, money);//给to加上相应金额
    			
    			//提交事务
    			ct.commit();
    			ct.close();
    		} catch(Exception e) {
    			//回滚事务
    			try {
    				ct.rollback();
    				ct.close();
    			} catch (SQLException e1) {
    			}
    			throw new RuntimeException(e);
    		}
    	}
    	
    
    }
    


     

  • 相关阅读:
    Servlet笔记2--模拟Servlet本质、第一个Servlet程序、将响应结果输出到浏览器中
    Servlet笔记1--概述
    Spring笔记13--SSH--全注解开发
    Spring4笔记12--SSH整合3--Spring与Struts2整合
    Spring4笔记11--SSH整合2--SpringWeb
    Spring4笔记10--SSH整合1--Spring与Hibernate整合
    局部变量表
    阿里云centos7使用yum安装mysql的正确姿势
    shell parameter
    maven 坐标
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467264.html
Copyright © 2011-2022 走看看