目录


JDBC 事务应用

Oracle 中的事务

  1. 在默认情况下,每执行一条增、删、改 SQL 语句,都是一个单独的事务。如果需要在一个事务中包含多条 SQL 语句,那么需要开启事务和结束事务。
  2. 结束事务:commit 或 rollback
  3. 在执行增、删、改一条 SQL 就开启了一个事务(事务的起点),然后可以去执行多条 SQL 语句,最后要结束事务,commit 表示提交,即事务中的多条 SQL 语句所做出的影响会持久化到数据库中。或者 rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都被撤消了!
  4. 下面演示 魏宇轩 给 wyx 转账 1000 元的示例
  5. UPDATE account SET balance=balance-10000 WHERE id=1;
    UPDATE account SET balance=balance+10000 WHERE id=2;
    ROLLBACK;--回滚
    UPDATE account SET balance=balance-10000 WHERE id=1;
    UPDATE account SET balance=balance+10000 WHERE id=2;
    COMMIT;--提交

jdbc 中的事务

  1. Connection 的三个方法与事务相关:
    ① setAutoCommit(boolean):设置是否为自动提交事务,如果 true(默认值就是 true)表示自动提交,也就是每条执行的 SQL语句都是一个单独的事务,如果设置 false,那么就相当于开启了事务了;
    ② commit():提交结束事务;
    ③ rollback():回滚结束事务。

  2. 初始状态
    JDBC基础(12)_JDBC事务应用_sql

  3. 出现异常
    JDBC基础(12)_JDBC事务应用_sql_02
    JDBC基础(12)_JDBC事务应用_JDBC_03

  4. 未出现异常
    JDBC基础(12)_JDBC事务应用_事务应用_04
    JDBC基础(12)_JDBC事务应用_回滚_05

源码

  • DBUtils 类
  • package com.wyx.jdbc.utils;

    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;

    public class DBUtils
    {
    public static Connection getConn()
    {
    InputStream in = DBUtils.class.getClassLoader().getResourceAsStream(
    "db.properties");
    Properties prop = new Properties();
    Connection conn = null;
    try
    {
    prop.load(in);
    String driverClass = prop.getProperty("driverClass");
    String url = prop.getProperty("url");
    String username = prop.getProperty("username");
    String password = prop.getProperty("password");
    // 注册驱动
    Class.forName(driverClass);
    conn = DriverManager.getConnection(url, username, password);
    } catch (Exception e)
    {
    e.printStackTrace();
    }
    return conn;
    }

    public static PreparedStatement getPstmt(String sql)
    {
    Connection conn = getConn();
    PreparedStatement pstmt = null;
    try
    {
    pstmt = conn.prepareStatement(sql);
    } catch (SQLException e)
    {
    e.printStackTrace();
    }
    return pstmt;
    }

    public static void closeUpdateRes(PreparedStatement ps)
    {
    if (ps != null)
    {
    try
    {
    Connection conn = ps.getConnection();
    ps.close();
    if (conn != null)
    {
    conn.close();
    }
    } catch (SQLException e)
    {
    e.printStackTrace();
    }
    }
    }

    public static void closeQueryRes(ResultSet rs)
    {
    if (rs != null)
    {
    Statement pstmt;
    try
    {
    pstmt = rs.getStatement();
    if (pstmt != null)
    {
    Connection conn = pstmt.getConnection();
    rs.close();
    pstmt.close();
    if (conn != null)
    {
    conn.close();
    }
    }
    } catch (SQLException e)
    {
    e.printStackTrace();
    }
    }
    }
    }
  • 主类 JDBCTran
  • package com.wyx.jdbc;

    import java.math.BigDecimal;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    import com.wyx.jdbc.utils.DBUtils;

    public class JDBCTran
    {
    public static void main(String[] args)
    {
    String sql = "update myaccount t set t.blance = t.blance - ? where t.id =?";
    String sql2 = "update myaccount t set t.blance = t.blance + ? where t.id =?";
    Connection conn = DBUtils.getConn();

    PreparedStatement ps = null;
    PreparedStatement ps1 = null;
    try
    {
    ps = conn.prepareStatement(sql);
    ps1 = conn.prepareStatement(sql);

    // 设置事务是手动提交,让当前的连接connection的所有的数据库变更的sql都在同一个事务之内,要么同时成功,要么同时失败
    conn.setAutoCommit(false);
    ps.setBigDecimal(1, new BigDecimal(1000));
    ps.setInt(2, 1);
    ps.executeUpdate();

    // 在两个事物执行途中抛出异常,查看是否同时成功同时失败
    if (false)
    {
    throw new Exception();
    }

    ps1.setBigDecimal(1, new BigDecimal(1000));
    ps1.setInt(2, 2);
    ps1.executeUpdate();
    // 手动提交事务
    conn.commit();
    } catch (Exception e)
    {
    try
    {
    // 如果发生异常事务就回滚
    conn.rollback();
    } catch (SQLException e1)
    {
    e1.printStackTrace();
    }
    e.printStackTrace();
    } finally
    {
    DBUtils.closeUpdateRes(ps1);
    DBUtils.closeUpdateRes(ps);
    }
    }
    }

为了方便,直接提供源码文件,请使用 MyEclipse 导入工程打开查看,点此下载。

如有错误,欢迎指正!