批处理

Batch

  • 对于大量的批处理,建议使用Statement,因为PreparedStatement的预编译空间有限,当数据量特别大时,会发生异常

Code

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 批处理的基本用法
 * @author Matrix42
 *
 */
public class Demo05 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");
            stmt = conn.createStatement();
            //把事物设置为手动提交
            conn.setAutoCommit(false);
            long start = System.currentTimeMillis();
            for(int i=0;i<20000;i++){
                stmt.addBatch("insert into t_user(username,pwd,regTime) values('matrix"+i+"',666666,now())");
            }
            stmt.executeBatch();

            //提交事物
            conn.commit();
            long end = System.currentTimeMillis();
            System.out.println("插入20000条数据,耗时(ms):"+(end-start));

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //关闭连接
    }
}

事务

事物的概念

  • 一组要么同时执行成功,要么同时执行失败的SQL语句.是数据库操作的一个执行单元

  • 事务开始于:

    • 连接到数据库上,并执行一条DML语句(INSERT,UPDATE或DELETE)

    • 前一个事务结束后,又输入了另外一条DML语句

  • 事务结束于:

    • 执行COMMIT或ROLLBACK语句

    • 执行一条DDL语句,例如CREATE TABLE语句;在这种情况下会自动执行COMMIT语句

    • 执行一条DCL语句,例如GRANT语句;在这种情况下,会自动执行COMMIT语句

    • 断开与数据库的连接

    • 执行了一条DML语句,改语句却失败了;在这种情况下,会为这个无效的DML语句执行ROLLBACK语句

事物的四大特性(ACID)

  • atomicity(原子性)

    • 表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败
  • consistency(一致性)

    • 表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前的状态
  • isolation(隔离性)

    • 事务查看数据时数据所处的状态,要么是另一个并发事物修改它之前的状态,要么是另一事物修改它之后的状态,事物不会查看中间状态的数据
  • durablity(持久性)

    • 持久性事物完成之后,它对于系统的影响是永久性的

事务隔离级别从低到高

  • 读取未提交(Read Uncommitted)

  • 读取已提交(Read Committed)(默认)

  • 可重复读(Repleatable Read)

  • 序列化(serializable)

Code

第二条会报错,会回滚

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

/**
 * 事务的基本用法
 * @author Matrix42
 *
 */
public class Demo06 {
    public static void main(String[] args) throws InterruptedException {
        Connection conn = null;
        PreparedStatement ps = null;
        PreparedStatement ps1 = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");

            //JDBC中默认自动提交事物
            conn.setAutoCommit(false);

            String sql = "insert into t_user(username,pwd) values(?,?)";

            ps = conn.prepareStatement(sql);
            ps.setObject(1, "Matrix42");
            ps.setObject(2, 123456);
            ps.execute();
            System.out.println("插入一个用户!");

            Thread.sleep(6000);

            ps1 = conn.prepareStatement("insert into t_user(username,pwd) values(?,?,?)");
            ps1.setObject(1, "Matrix42");
            ps1.setObject(2, 123456);
            ps1.execute();
            System.out.println("插入另外一个用户!");

            conn.commit();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        } catch (SQLException e) {
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }

        //关闭连接
    }
}