千家信息网

JDBC系列:(7)使用Connection操作事务

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,事务ACID特性序号特性描述1原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。2一致性(Consistency)事务必须使数据库从一个一致性状
千家信息网最后更新 2024年09月22日JDBC系列:(7)使用Connection操作事务
事务ACID特性
序号特性描述
1原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
4持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响




Connection操作事务的相关方法
序号方法作用
1void setAutoCommit(boolean autoCommit)设置事务是否自动提交
如果设置为false,表示手动提交事务。
2void commit() ()手动提交事务
3void rollback()回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)
4Savepoint setSavepoint(String name)在当前事务中创建一个保存点


1、使用事务

package com.rk.db.g_transaction;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import com.rk.db.utils.JDBCUtil;/** * // 转账,使用事务 * @author RK * */public class Demo01{        public static void main(String[] args)        {                Connection conn = null;                try                {                        conn = JDBCUtil.getConnection();                        // 1、设置事务为手动提交                        conn.setAutoCommit(false);                        boolean flag = true; //表示是否出现SQL异常                        transferMoney(conn, 100, "张三", "李四",flag);                }                catch (SQLException e)                {                        System.out.println("转账失败!");                        try                        {                                // 2、 出现异常,需要回滚事务                                conn.rollback();                                System.out.println("回滚操作成功!!!");                        }                        catch (SQLException ex)                        {                                ex.printStackTrace();                        }                }                finally                {                        // 3、所有的操作执行成功, 提交事务                        try                        {                                conn.commit();                                System.out.println("执行完毕!");                        }                        catch (SQLException e)                        {                                e.printStackTrace();                        }                        JDBCUtil.closeQuietly(conn);                }        }        /**         * 模拟银行转账         * @param conn 数据库连接         * @param moneyNum 转账的金额         * @param userAdd 收到Money的用户         * @param userSub 支出Money的用户         * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现         * @throws SQLException         */        private static void transferMoney(Connection conn,                         long moneyNum, String userAdd, String userSub,                        boolean flag) throws SQLException        {                PreparedStatement pstmtAdd = null;                PreparedStatement pstmtSub = null;                try                {                        String sqlAddMoney = "update T_Bank set money=money+? where username=?";                        pstmtAdd = conn.prepareStatement(sqlAddMoney);                        pstmtAdd.setLong(1, moneyNum);                        pstmtAdd.setString(2, userAdd);                        pstmtAdd.executeUpdate();                                                if(flag)                        {                                throw new SQLException("模拟SQL执行出错");                        }                        String sqlSubMoney = "update T_Bank set money=money-? where username=?";                        pstmtSub = conn.prepareStatement(sqlSubMoney);                        pstmtSub.setLong(1, moneyNum);                        pstmtSub.setString(2, userSub);                        pstmtSub.executeUpdate();                }                finally                {                        JDBCUtil.closeQuietly(pstmtAdd);                        JDBCUtil.closeQuietly(pstmtSub);                }        }}



2、使用事务,回滚到指定的代码段

package com.rk.db.g_transaction;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Savepoint;import com.rk.db.utils.JDBCUtil;/** * // 转账,使用事务, 回滚到指定的代码段 * @author RK * */public class Demo02{        public static void main(String[] args)        {                Connection conn = null;                Savepoint sp = null;                try                {                        conn = JDBCUtil.getConnection();                        // 1、设置事务为手动提交                        conn.setAutoCommit(false);                        transferMoney(conn, 1000, "李四", "张三",false);                                                // 如果失败,回滚到这个位置                        sp = conn.setSavepoint();                                                boolean flag = true; //表示是否出现SQL异常                        transferMoney(conn, 500, "张三", "李四",flag);                }                catch (SQLException e)                {                        System.out.println("转账失败!");                        try                        {                                // 2、 出现异常,需要回滚 (回滚到指定的代码段)                                conn.rollback(sp);                                System.out.println("回滚到指定位置操作成功!!!");                        }                        catch (SQLException ex)                        {                                ex.printStackTrace();                        }                }                finally                {                        // 3、所有的操作执行成功, 提交事务                        try                        {                                conn.commit();                                System.out.println("执行完毕!");                        }                        catch (SQLException e)                        {                                e.printStackTrace();                        }                        JDBCUtil.closeQuietly(conn);                }        }        /**         * 模拟银行转账         * @param conn 数据库连接         * @param moneyNum 转账的金额         * @param userAdd 收到Money的用户         * @param userSub 支出Money的用户         * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现         * @throws SQLException         */        private static void transferMoney(Connection conn,                         long moneyNum, String userAdd, String userSub,                        boolean flag) throws SQLException        {                PreparedStatement pstmtAdd = null;                PreparedStatement pstmtSub = null;                try                {                        String sqlAddMoney = "update T_Bank set money=money+? where username=?";                        pstmtAdd = conn.prepareStatement(sqlAddMoney);                        pstmtAdd.setLong(1, moneyNum);                        pstmtAdd.setString(2, userAdd);                        pstmtAdd.executeUpdate();                                                if(flag)                        {                                throw new SQLException("模拟SQL执行出错");                        }                        String sqlSubMoney = "update T_Bank set money=money-? where username=?";                        pstmtSub = conn.prepareStatement(sqlSubMoney);                        pstmtSub.setLong(1, moneyNum);                        pstmtSub.setString(2, userSub);                        pstmtSub.executeUpdate();                }                finally                {                        JDBCUtil.closeQuietly(pstmtAdd);                        JDBCUtil.closeQuietly(pstmtSub);                }        }}





0