• JDBC——事物管理


    案例:银行转账问题,数据库如下

    相关API

    setAutoCommit(boolean autoCommit)  将此连接的自动提交模式设置为给定状态。设置事务是否自动提交如果设置为false,表示手动提交事务

    setSavepoint() 在当前事务中创建一个未命名的保存点 (savepoint),并返回表示它的新 Savepoint 对象。

    void rollback() ;     回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)

    java.sql接口 Savepoint  public interface Savepoint   保存点的表示形式,保存点是可以从 Connection.rollback 方法引用的当前事务中的点。将事务回滚到保存点时,在该保存点之后所作的全部更改都将被撤消。 

    // 1. 转账
    	public void trans1() {
    
    		String sql_zs = "UPDATE account SET money=money-1000 WHERE name='张三';";
    		String sql_ls = "UPDATE account SET money=money+1000 WHERE name='李四';";
    
    		try {
    			con = JDBCU.getConnection(); // 默认开启的隐士事务
    			con.setAutoCommit(true);//默认值是true,写不写一样
    
    			/*** 第一次执行SQL ***/
    			pstmt = con.prepareStatement(sql_zs);
    			pstmt.executeUpdate();
    
    			/*** 第二次执行SQL ***/
    			pstmt = con.prepareStatement(sql_ls);
    			pstmt.executeUpdate();
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			JDBCU.closeAll(con, pstmt, null);
    		}
    
    	}
    

     


     

    当一方出现问题,这个时候需要管理,除了两者都提交成功外,其他的都回滚原来状态

    @Test
    	// 2. 转账,使用事务
    	public void trans2() {
    
    		String sql_zs = "UPDATE account SET money=money-1000 WHERE name='张三';";
    		//故意出错,数据库会出错。
    		String sql_ls = "UPDATE account SET money=money1+1000 WHERE name='李四';";
    
    		try {
    			con = JDBCU.getConnection(); // 默认开启的隐士事务
    			// 一、设置事务为手动提交
    			con.setAutoCommit(false);
    
    			/*** 第一次执行SQL ***/
    			pstmt = con.prepareStatement(sql_zs);
    			pstmt.executeUpdate();
    
    			/*** 第二次执行SQL ***/
    			pstmt = con.prepareStatement(sql_ls);
    			pstmt.executeUpdate();
    
    		} catch (Exception e) {
    			try {
    				// 二、 出现异常,需要回滚事务
    				con.rollback();
    			} catch (SQLException e1) {
    			}
    			e.printStackTrace();
    		} finally {
    			try {
    				// 三、所有的操作执行成功, 提交事务
    				con.commit();
    				JDBCU.closeAll(con, pstmt, null);
    			} catch (SQLException e) {
    			}
    		}
    
    	}
    

    回滚到指定的代码段

    // 3. 转账,使用事务, 回滚到指定的代码段
    	//第一次有错误,而第二次有错误,现在想在第一次和第二次之间设置一个还原点
    	@Test
    	public void trans() {
    		// 定义个标记
    		Savepoint sp = null;
    		
    		// 第一次转账
    		String sql_zs1 = "UPDATE account SET money=money-1000 WHERE accountName='张三';";
    		String sql_ls1 = "UPDATE account SET money=money+1000 WHERE accountName='李四';";
    		
    		// 第二次转账
    		String sql_zs2 = "UPDATE account SET money=money-500 WHERE accountName='张三';";
    		String sql_ls2 = "UPDATE1 account SET money=money+500 WHERE accountName='李四';";
    
    		try {
    			con = JDBCU.getConnection(); // 默认开启的隐士事务
    			con.setAutoCommit(false);       // 设置事务手动提交
    
    			/*** 第一次转账 ***/
    			pstmt = con.prepareStatement(sql_zs1);
    			pstmt.executeUpdate();
    			pstmt = con.prepareStatement(sql_ls1);
    			pstmt.executeUpdate();
    			
    			// 回滚到这个位置?
    			sp = con.setSavepoint(); 
    			
    			
    			/*** 第二次转账 ***/
    			pstmt = con.prepareStatement(sql_zs2);
    			pstmt.executeUpdate();
    			pstmt = con.prepareStatement(sql_ls2);
    			pstmt.executeUpdate();
    			
    
    		} catch (Exception e) {
    			try {
    				// 回滚 (回滚到指定的代码段)
    				con.rollback(sp);
    			} catch (SQLException e1) {
    			}
    			e.printStackTrace();
    		} finally {
    			try {
    				// 提交
    				con.commit();
    			} catch (SQLException e) {
    			}
    			JDBCU.closeAll(con, pstmt, null);
    		}
    
    	}
    

      

  • 相关阅读:
    Linux Ctrl+Z的使用方法
    cx_Oracle库导入失败引起crontab中python程序运行失败,并且无错误提示
    cx_Oracle库导入失败引起crontab中python程序运行失败,并且无错误提示
    python __file__ 与相对路径
    ORACLE之手动注册监听listener。alter system set local_listener="XXX"
    pl/sql developer 连接本地ORACLE 11g 64位数据库
    在linux设置环境变量
    通过Instant Client包来使用SQL*PLUS
    linux 安装oracle 11g
    plsql developer 使用技巧
  • 原文地址:https://www.cnblogs.com/helloworldcode/p/6074490.html
Copyright © 2020-2023  润新知