美文网首页
黑猴子的家:JDBC -> mysql 事务案例实操

黑猴子的家:JDBC -> mysql 事务案例实操

作者: 黑猴子的家 | 来源:发表于2019-03-02 05:55 被阅读1次
    1、准备数据

    (1)数据信息

    id username balance
    1 张三丰 1000
    2 郭襄 1000

    (2)表信息

    create table account(
        id int NOT NULL AUTO_INCREMENT,
        username varchar(20),
        balance varchar(20)
    )
    truncate table account;
    select * from account;
    insert into account(username,balance)values(‘张三丰’,1000);
    insert into account(username,balance)values(‘郭襄’,1000);
    
    2、没有使用事务
    package com.yinggu.demo6;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import org.junit.Test;
    import com.yinggu.utils.JDBCUtils;
    import com.yinggu.utils.MyCRUDUtils;
    
     * 此类用于演示事务
    * @author:黑猴子的家
    * @博客 :https://www.jianshu.com/u/37fd8e2dff4c
    * 场景: Account: 张三丰 1000 郭襄 1000 转账:张三丰给郭襄转账 500
    *  事务的使用步骤:
    *         1.取消自动提交 set autocommit=0;
    *         2.开启事务【可选】 start transaction
    *         3.事务的操作
    *         4.提交或回滚 commit或rollback
    *         注意: 开启事务的连接对象和事务执行语句的连接对象必须是同一个!!!!
    
    public class TestTransaction {
          // 没有使用事务
          @Test
          public void testNoTransaction() throws Exception {
                // 1.获取连接
                Connection connection = JDBCUtils.getConnection();
                // 2.访问
                PreparedStatement statement = connection.prepareStatement(
                    "update account set balance = ? where username=?");
                // 更新张三丰的余额
                statement.setFloat(1, 500);
                statement.setString(2, "张三丰");
                statement.executeUpdate();
                // 演示异常
                int i = 1 / 0;
                // 更新郭襄的余额
                statement.setFloat(1, 1500);
                statement.setString(2, "郭襄");
                statement.executeUpdate();
                // 3.关闭
                JDBCUtils.closeConnection(null, statement, connection);
          }
    }
    
    3、使用了事务1
    // 使用事务1
    @Test
    public void testUseTransaction1() {
        // 1.获取连接
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = JDBCUtils.getConnection();
            // 2.访问
            // 事务使用步骤1:开启事务
            connection.setAutoCommit(false);
            statement = connection.prepareStatement(
                    "update account set balance = ? where username=?");
            // 更新张三丰的余额
            statement.setFloat(1, 500);
            statement.setString(2, "张三丰");
            statement.executeUpdate();
            // 演示异常
            // int i = 1 / 1;
            int i = 1 / 0;
            // 更新郭襄的余额
            statement.setFloat(1, 1500);
            statement.setString(2, "郭襄");
            statement.executeUpdate();
            // 事务使用步骤2:提交
            connection.commit();
        } catch (Exception e) {
            // 事务使用步骤3:回滚
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                // 3.关闭
                JDBCUtils.closeConnection(null, statement, connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    4、使用了事务2
    // 使用事务2
    明明使用了事务, 却没有达到事务数据的一直性
    原因是,使用工具类,开始连接事务的连接和执行语句的连接不是一个连接
    注意: 开启事务的连接对象和事务执行语句的连接对象必须是同一个!!!
    @Test
    public void testUseTransaction2() {
        // 1.获取连接
        Connection connection = null;
        try {
            connection = JDBCUtils.getConnection();
            // 2.访问
            // 事务使用步骤1:开启事务
            connection.setAutoCommit(false);
            // 事务的操作1:更新张三丰
            MyCRUDUtils.update(connection,
                "update account set balance = ? where username=?", 500, "张三丰");
            // MyCRUDUtils.update( "update account set balance = ? where
            // username=?", 500, "张三丰");
            // 模拟异常
            int i = 1 / 0;
            // 事务的操作1:更新郭襄
            MyCRUDUtils.update(connection,
                "update account set balance = ? where username=?", 1500, "郭襄");
            // 事务使用步骤2:提交
            connection.commit();
        } catch (Exception e) {
            // 事务使用步骤3:回滚
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                // 3.关闭
                JDBCUtils.closeConnection(null, null, connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:黑猴子的家:JDBC -> mysql 事务案例实操

          本文链接:https://www.haomeiwen.com/subject/zvdduqtx.html