JDBC--(7)批处理、事务

JDBC批处理

什么是批处理

  1. 一次性执行多条Sql语句,允许多条语句一次性提交给数据库批量处理
  2. 比单独提交处理要效率高

批处理方法
addBatch(String) 添加需要批处理的sql语句
executeBatch() 执批处理

支持情况

  1. mysql默认情况下是不支持批处理的
  2. 从5.1.13开始,添加了一个rewriteBatchedStatements参数
    之前插入10条数据要17.4秒
    从5.1.13开始提高到了1.6秒
    在这里插入图片描述
package com.iris.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import com.iris.jdbc.util.JDBCUtil;

public class BatchTest {
	public static void main(String[] args) throws Exception {
		Connection conn = JDBCUtil.getConn();
		String sql = "insert into student (name,age) values (?,?)";
		PreparedStatement ps = conn.prepareStatement(sql);
		long begin = System.currentTimeMillis();
		for (int i=0;i < 100; i++) {
			ps.setString(1, "zs");
			ps.setInt(2, 10);
			//添加批处理
			ps.addBatch();
		}
		//执行批处理
		ps.executeBatch();
		long end = System.currentTimeMillis();
		
		long time = end -begin;
		System.out.println(time);
		
		JDBCUtil.close(conn, ps, null);
	}
}

什么都不添加执行100此循环的时间
在这里插入图片描述
添加 addBatch(String)executeBatch() 执批处理 执行100此循环的时间

在这里插入图片描述
添加 rewriteBatchedStatements=True 参数后执行100次循环的时间
在这里插入图片描述

JDBC事务问题

建立一张个人账户表
在这里插入图片描述
zs 和 ls 进行转账

  1. 检查zs账户余额
  2. 减少zs账户1000
  3. 增加ls账户1000
package com.iris.jdbc.test;

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

import com.iris.jdbc.util.JDBCUtil;

public class TransactionTest {
	public static void main(String[] args) throws SQLException {
		//1. 检查zs账户余额
		//2. 减少zs账户1000
		//3. 增加ls账户1000
		
		Connection conn = JDBCUtil.getConn();
		String sql = "select * from account where name = ? and money >?";
		//创建语句
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, "zs");
		ps.setInt(2, 1000);
		ResultSet res = ps.executeQuery();
		if(!res.next()) {
			throw new RuntimeException("没钱了");
		}
		//2. 减少zs账户1000
		sql = "update account set money = money - ? where name = ?";
		ps = conn.prepareStatement(sql);
		ps.setDouble(1, 1000);
		ps.setString(2, "zs");
		ps.executeUpdate();
		//3. 增加ls账户1000
		sql = "update account set money = money + ? where name = ?";
		ps = conn.prepareStatement(sql);
		ps.setDouble(1, 1000);
		ps.setString(2, "ls");
		ps.executeUpdate();
		
		JDBCUtil.close(conn, ps, res);
		System.out.println("完成");
	}
}

在这里插入图片描述
多次转账之后报异常
在这里插入图片描述
出现异常情况
在第2步和第3步之间弄一个异常 int a = 1 / 0;
一个人的账户减少,另一个没有加

处理事务

默认情况下, 事务是自动提交的
要设置为手动提交

处理事务过程

关闭自动提交conn.setAutoCommit(false);
没有问题时,提交事务 conn.commit();
出现异常时,进行回滚操作conn.rollback()
  回滚之后,事务结束。释放资源
  出现异常,没有提交,也不会更新数据库,但是会占用资源
  所以要出现异常时,进行回滚操作
只有增、册、改才需要事务,查询不需要事务
以后发现自己写的代码是正确的,测试也成功,但是数据库当中的数据不变(事务没有提交)
InnoDB才支持外键和事务。MyISAM不支持外键和事务
设置事务的隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_REPATABLE_READ)

package com.iris.jdbc.test;

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

import com.iris.jdbc.util.JDBCUtil;

public class TransactionTest {
	public static void main(String[] args) throws SQLException {
		//1. 检查zs账户余额
		//2. 减少zs账户1000
		//3. 增加ls账户1000
		
		Connection conn = JDBCUtil.getConn();
		String sql = "select * from account where name = ? and money >?";
		//创建语句
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, "zs");
		ps.setInt(2, 1000);
		ResultSet res = ps.executeQuery();
		if(!res.next()) {
			throw new RuntimeException("没钱了");
		}
		
		try {
			// 开启事务
			conn.setAutoCommit(false);
			//2. 减少zs账户1000
			sql = "update account set money = money - ? where name = ?";
			ps = conn.prepareStatement(sql);
			ps.setDouble(1, 1000);
			ps.setString(2, "zs");
			ps.executeUpdate();
			
			//3. 增加ls账户1000
			sql = "update account set money = money + ? where name = ?";
			ps = conn.prepareStatement(sql);
			ps.setDouble(1, 1000);
			ps.setString(2, "ls");
			ps.executeUpdate();
			
			//提交事务
			conn.commit();
			
		}catch(Exception e) {
			e.printStackTrace();
			conn.rollback();
		}finally {
			JDBCUtil.close(conn, ps, res);
		}
		System.out.println("完成");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值