关于JDBC演示事务和批处理

这周在学数据库,以及和JDBC连接数据库进行操作。首先看看JDBC如何处理事务和批处理吧。

演示事务

idea中try catch快捷键: Ctrl + win + Alt + t

事务的四大属性

  1. 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都失败。
  2. 一致性(Consistency):事务必须使数据库从一个一致性状态转换到另一个一致性状态。
  3. 隔离性(Isolation):一个事务的执行不能被另一个事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不会互相干扰。
  4. 持久性(Durability):一个事务一旦被提交,它对数据库中的数据的操作是持久性的,接下来的其他操作或者数据库故障都不对它产生任何影响。

事务使用步骤

  1. 开启新事务

    取消隐式事务自动提交的功能。

  2. 编写组成事务的一组sql语句

  3. 结束事务

    • commit();提交
    • rollback();回滚

!注意:

开启事务的连接对象和获取命令的连接对象必须是同一个!否则事务无效。

使用和不用事务的区别

  • 不用事务 : 异常前后的语句执行情况不同。只能执行异常前的,异常后的无效。
  • 使用事务 : 可以根据有无异常自动执行提交事务或回滚。
import com.miyon.jdbc.JDBCUtils;
import org.junit.Test;

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

/**
 * 演示JDBC中的事务:
 *
 *使用步骤:
 *  1.开启新事务,取消隐式事务自动提交的功能
 *  setAutoCommit(false);
 *  2.编写组成事务的一组sql语句
 *
 *  3.结束事务
 *  commit();提交
 *  rollback();回滚
 *
 *  !注意:
 *  开启事务的连接对象和获取命令的连接对象必须是同一个!否则事务无效。
 *
 */
public class TestTransaction {
    //不用事务 : 异常前后的语句执行情况不同。
    @Test
    public void testNoTransaction() throws Exception{

        //1.获取连接
        Connection connection = JDBCUtils.getConnection2();
        //2.编写语句
        PreparedStatement statement = connection.prepareStatement("UPDATE stronginfo SET height=? WHERE id=?");

        //2.1  设置id为1 的身高为100
        statement.setInt(1,100);
        statement.setInt(2,1);
        statement.executeUpdate();

        int i = 1/0; //模拟异常   异常前面的身高改变,后面的没有变化。

        //2.2  设置id为2 的身高为200
        statement.setInt(1,200);
        statement.setInt(2,2);
        statement.executeUpdate(); 

        //3.释放资源
        JDBCUtils.close(null,statement,connection);
    }

    
    //使用事务 : 可以根据有无异常自动执行提交事务或回滚。
    @Test
    public void testTransaction() {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            //1.获取连接
            connection = JDBCUtils.getConnection2();

            //2.使用事务

            //事务的使用步骤①:开启事务
            connection.setAutoCommit(false);//取消事务自动开启,开启事务。

            //事务的使用步骤②:编写sql语句并执行
            statement = connection.prepareStatement("UPDATE stronginfo SET height=? WHERE id=?");

            //  设置id为1 的身高为175
            statement.setInt(1,100);
            statement.setInt(2,1);
            statement.executeUpdate();

//            int i = 1/0;
            //模拟异常,使用事务时,遇到异常,发生回滚,数据没有发生变化。
//            int i = 1/0;
            //没有异常时,正常结束事务,执行语句,数据发生变化。

            //  设置id为2 的身高为205
            statement.setInt(1,99);
            statement.setInt(2,2);
            statement.executeUpdate();

            //事务的使用步骤③:结束事务
            connection.commit();
        } catch (SQLException throwables) {
            try {
                //事务回滚
                connection.rollback();
            } catch (SQLException e) {
            }
        }finally {
            try {
                JDBCUtils.close(null,statement,connection);
            } catch (Exception e) {
            }
        }
    }
}

批处理

- mysql默认批处理是关闭的,所以我们还需要去打开mysql的批处理:
rewriteBatchedStatements=true
我们需要将以上的参数添加到mysql的url地址中。

- 注意:低版本的mysql-jdbc驱动也不支持批处理,一般都是在修改的时候使用批处理,查询的时候不使用

相关API:

  • addBatch();
  • executeBatch();
  • clearBatch();

说明:

批处理往往和PreparedStatement一起搭配使用,既可以减少编译次数,又能减少运行次数,大大提高效率!

import com.miyon.jdbc.JDBCUtils;
import org.junit.Test;

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

/**
* 演示批处理的使用
*
* 案例:
* 向admin表中插入50000行数据;
* 
*
*/
public class TestBatch {
   //不使用批处理
   @Test
   public void testNoBatch() throws Exception {
       //1.获取连接
       Connection connection = JDBCUtils.getConnection();

       //2.执行插入
       PreparedStatement statement = connection.prepareStatement("INSERT INTO admin values(null,?,?)");

       for (int i = 0; i < 50000; i++) {
           statement.setString(1,"john"+i);
           statement.setString(2,"0000");
           //执行
           statement.executeUpdate();
       }
       //3.关闭连接
       JDBCUtils.close(null,statement,connection);
   }

   //使用批处理
   @Test
   public void testBatch() throws Exception{
       //1.获取连接
       Connection connection = JDBCUtils.getConnection();

       //2.执行插入
       PreparedStatement statement = connection.prepareStatement("INSERT INTO admin values(null,?,?)");

       for (int i = 0; i <= 500000; i++) {
           statement.setString(1,"john"+i);
           statement.setString(2,"0000");
           //执行
           statement.addBatch();         //将sql语句添加到批处理包中
           if(i%10000==0){                //每1000条执行一次
               statement.executeBatch();//执行批处理包中的sql语句
               statement.clearBatch();   //清空批处理包中的sql语句
           }
       }
       //3.关闭连接
       JDBCUtils.close(null,statement,connection);
   }
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容