码迷,mamicode.com
首页 > 数据库 > 详细

dljd_(018-020)_jdbc中mysql的事务管理

时间:2018-12-07 11:59:14      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:结果   .exe   mysql管理   实现   main   row   出现   例子   name   

一、通过debug模式验证jdbc中mysql管理事务的默认方式(自动提交)示例

package edu.aeon.jdbc;

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

import edu.aeon.aeonutils.AeonJdbcUtils;
/**
 * [说明]:验证jdbc中mysql管理事务的默认方式(自动提交)
 * @author aeon
 */
public class TestJDBC {
    /**
     * 使用jdbc中mysql管理事务的默认方式(自动提交)验证
     */
    public static void jdbc_insert(){
        Connection connection=null;
        PreparedStatement preparedStatement = null;
        try {
            connection = AeonJdbcUtils.getMySqlConnection();
            String sql="insert into user(userid,username,userpw) values (?,?,?)";
            //第一条数据
            //将sql语句进行预编译然后保存到preparedStatement对象中
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 10006);
            preparedStatement.setString(2, "aeon6");
            preparedStatement.setString(3, "aeon6");
            int rowCount = preparedStatement.executeUpdate();
            System.out.println(rowCount+"条数据被插入!");
            
            //第二条数据
            preparedStatement.setInt(1, 10007);
            preparedStatement.setString(2, "aeon7");
            preparedStatement.setString(3, "aeon7");
            rowCount = preparedStatement.executeUpdate();
            System.out.println(rowCount+"条数据被插入!");
            //第三条数据
            preparedStatement.setInt(1, 10008);
            preparedStatement.setString(2, "aeon8");
            preparedStatement.setString(3, "aeon8");
            rowCount = preparedStatement.executeUpdate();
            System.out.println(rowCount+"条数据被插入!");
            //第四条
            preparedStatement.setInt(1, 10006);//模拟错误
            preparedStatement.setString(2, "aeon9");
            preparedStatement.setString(3, "aeon9");
            rowCount = preparedStatement.executeUpdate();
            System.out.println(rowCount+"条数据被插入!");
            //第五条数据
            preparedStatement.setInt(1, 100010);
            preparedStatement.setString(2, "aeon10");
            preparedStatement.setString(3, "aeon10");
            rowCount = preparedStatement.executeUpdate();
            System.out.println(rowCount+"条数据被插入!");
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            AeonJdbcUtils.closeDB(null, preparedStatement, connection);
        }
    }
    public static void main(String[] args) {
        jdbc_insert();
    }
}

执行结果截图:

  技术分享图片

  数据库截图:

  技术分享图片

  当我们在debug模式下执行完第一条数据后执行第二条数据前,我们可以看到第一条数据已经被插入到数据库当中了、因此可以判断出第一条事务被默认的提交到数据库当中了。

  当在执行第四条语句的时候出了主键冲突作用、但是这个错误不会影响到前三条数据的正常执行(这就是鉴于事物的原子行)

  当第四条语句(事务)出错后,那么第五条数据是不会被正常执行的!

二、这种jdbc中mysql的默认提交事务在某些场合下并不使用

  比如说进行转账操作时、a 卡向b卡转账 100万元

  当程序跑到a卡里面的钱被扣了100万元后、b卡里面的钱没有被加前、突然停电了、那么这种情况就是a持卡人说我向你转了100万、而b持卡人说我根本没有收到100万、我们怎么在程序里面避免这种现象的发生?(将a卡扣钱事务和b卡的加钱事务放到一个事务当中)、当扣钱和加钱同时执行成功,则本次转账成功、否则当次事务中的任何一个操作出现异常的情况下视为本事务执行失败,恢复到转账前。

  2.1实现(在事务执行之前将事务的提交方式改为手动提交)

  此处由于本人比较小懒、就不模拟转账操作了(设计到转账还要从新见测试表)、我们拿之前的例子说明即可(因为原理一样):

  

package edu.aeon.jdbc;

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

import edu.aeon.aeonutils.AeonJdbcUtils;
/**
 * [说明]:修改jdbc中事务的提交方式
 * @author aeon
 */
public class TestJDBC {
    /**
     * @throws SQLException 
     */
    public static void jdbc_insert() throws SQLException{
        Connection connection=null;
        PreparedStatement preparedStatement = null;
        try {
            connection = AeonJdbcUtils.getMySqlConnection();
            //设置事务的提交方式为手动提交
            connection.setAutoCommit(false);
            String sql="insert into user(userid,username,userpw) values (?,?,?)";
            //第一条数据
            //将sql语句进行预编译然后保存到preparedStatement对象中
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 10006);
            preparedStatement.setString(2, "aeon6");
            preparedStatement.setString(3, "aeon6");
            int rowCount = preparedStatement.executeUpdate();
            //第二条数据
            preparedStatement.setInt(1, 10007);
            preparedStatement.setString(2, "aeon7");
            preparedStatement.setString(3, "aeon7");
            rowCount = preparedStatement.executeUpdate();
            //第三条数据
            preparedStatement.setInt(1, 10008);
            preparedStatement.setString(2, "aeon8");
            preparedStatement.setString(3, "aeon8");
            rowCount = preparedStatement.executeUpdate();
            //第四条
            preparedStatement.setInt(1, 10006);//模拟错误
            preparedStatement.setString(2, "aeon9");
            preparedStatement.setString(3, "aeon9");
            rowCount = preparedStatement.executeUpdate();
            //第五条数据
            preparedStatement.setInt(1, 100010);
            preparedStatement.setString(2, "aeon10");
            preparedStatement.setString(3, "aeon10");
            rowCount = preparedStatement.executeUpdate();
            //提交事务
            connection.commit();
            System.out.println("本次操作成功!");
            
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        } catch (SQLException e) {
            connection.rollback();
            System.out.println("本次操作失败!");
            e.printStackTrace();
        }finally {
            AeonJdbcUtils.closeDB(null, preparedStatement, connection);
        }
    }
    public static void main(String[] args) {
        try {
            jdbc_insert();
        } catch (SQLException e) {
            System.out.println("本次操作失败!");
            e.printStackTrace();
        }
    }
}

执行结果截图:

  技术分享图片  

 

数据库截图:

  技术分享图片

  当我们将这个模拟异常去掉后、执行结果截图:

  技术分享图片

 

  再去看看数据库:

   技术分享图片

  可见数据已经进来了!

  当使用jdbc修改了事务的提交方式为手动提交后、那么接下来执行的所有操作都将被放入到一个事务中了(commit()、rollback()之前的操作都将是一个事务)、当遇到commit()时将当前事务提交到数据库中、当遇到rollback()时,当前事务中的所有操作都将被撤回到事务执行之前(又恢复jdbc提交事务的默认方式)。

 

 

  

dljd_(018-020)_jdbc中mysql的事务管理

标签:结果   .exe   mysql管理   实现   main   row   出现   例子   name   

原文地址:https://www.cnblogs.com/aeon/p/10080899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!