JDBC总结——事务


事务

一、事务的基本介绍

1、概念

如果包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。

2、操作

  • ① 开启事务:start transaction;

  • ② 回滚:rollback;

  • ③ 提交:commit;

3、操作实例

account.sql

-- 创建account表
CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT;
	NAME VARCHAR(10),
	balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME,balance) VALUES ('zhangsan',1000),('lisi',1000);

SELECT * FROM account;
UPDATE account SET balance =1000;
--张三给李四转账500元

--0.开启事务
START TRANSACTION;
--1.张三账户-500
UPDATE account SET balance = balance - 500 WHERE NAME ='zhangsan';

--2.李四账户+500
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
--发现执行没有问题,提交事务
COMMIT;

--发现出现问题,回滚事务
ROLLBACK;

4、MySQL数据库中默认自动提交

事务提交的两种方式
1)自动提交

  • mysql是自动提交的
  • 一条DML(增删改)语句会自动提交一次事务

2)手动提交

  • Oracle 数据库默认是手动提交事务
  • 需要先开启事务,然后手动提交

修改事务的默认提价方式

  • 查看事务的默认提交方式:SElECT @@autocommit; --1 代表自动提交 0 代表手动提交

  • 修改默认提交方式:set @@autocommit = 0;

二、事务的四大特征

  • 原子性(atomicity) :事务必须是原子工作单元;对其数据修改,要么全都执行,要么全都不执行【最小的工作单位】

  • 一致性(consistency:事务在完成时,必须使所有的数据都保持一致状态【同时成功或者同时失败】

  • 隔离性(isolation):由并发事务所作的修改必须与任何其他并发事务所作的修改隔离【事务与事务之间相互不影响】

  • 持久性(durability):事务完成之后,它对于系统的影响是永久性的【事务一旦提交不可回滚】

三、事务的隔离级别

1、概念

多个事务之间隔离,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题:

2、存在的问题

  • ① 脏读:一个事务读取到另一个书屋中没有提交的数据

  • ② 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样

  • ③ 幻读:一个事务操作(DML)数据库中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

3、隔离级别

隔离的级别:

  • read uncommitted: 读未提交
    • 产生的问题:脏读,不可重复读,幻读
  • read committed: 读已提交
    • 产生的问题:不可重复读、幻读
  • repeatable read:可重复读
    • 产生的问题:幻读
  • serializable:串行化
    • 可以解决所有的问题

注意:隔离级别从小到大安全性越来越高,但是效率越来越低

隔离级别的设置

  • 数据库查询隔离级别:select @@tx_isolation;

  • 数据库设置隔离级别:set global transaction isolation level 级别字符串;

注:设置完隔离级别后需要重新打开mysql数据库才会生效。

演示

set global transaction isolation level read uncommitted;
start transaction;
-- 转账操作
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;

四、Jdbc事务控制

1、概述

  • 默认事务提交策略:一条命令自成一个完整事务
  • 需求:各个逻辑单元要么一起成功,要么一起失败(比如转账)

2、控制事务的API:

使用Connection对象来管理事务

  • conn.setAutoCommit(false); 将jdbc的事务计较改为手动提交
  • conn.commit(); 手动提交
  • conn.rollback(); 如果事务出错,就让他它回滚

注意:连接提交策略一经设置,永久改变。

3、核心代码

将JDBC自动提交关闭,改成手动提交,然后在让出错的事务在异常里捕获成回滚。这样保证了提交事务出错数据不改动。从而达到数据的正确性。

步骤:

 1. 获取连接Connection对象
 2.Connection对象开启事务
 3.Connection对象获取执行sql语句的Statement对象
 4.定义2条sql语句(2条update语句:扣款,收款)
 5.Statement对象执行sql语句,获取结果
 6.如果sql语句正常执行,没有出现问题,提交事务
 7.处理结果
 8.如果sql语句执行过程中出现问题,回滚事务
 9.关闭资源

代码:

import java.sql.*;

import util.JdbcUtil1;

/*
 * jdbc控制事务
 */
public class testTrasaction {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement pstm = null;
		PreparedStatement pstm1 = null;
		try {
			//获得连接
			conn = JdbcUtil1.getConnection();
			//设置jdbc手动提交
			conn.setAutoCommit(false);
			//降职ְ
			String sql = "update emp set job='clerk' where ename='陈美嘉'";
			pstm = conn.prepareStatement(sql);
			pstm.executeUpdate();
			//降薪
			String sql1 = "update emp set comm='300' where ename='陈美嘉'";
			pstm1 = conn.prepareStatement(sql1);
			pstm1.executeUpdate();
			//提交事务
			conn.commit();
		} catch (Exception e) {
			//事务回滚
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}finally{
			try {
				JdbcUtil1.release(null, pstm, null);
				JdbcUtil1.release(null, pstm1, conn);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}
	}
}

JdbcUtil1

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;

public class JdbcUtil1 {
	
	//声明properties
	static Properties pro = new Properties();
	//加载驱动
	static{
		InputStream is = null;
		try{
			is = JdbcUtil1.class.getResourceAsStream("/conf/db.properties");
			//加载文件
			pro.load(is);
			Class.forName(pro.getProperty("driverClassName"));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				is.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	//获取连接
	public static Connection getConnection() throws Exception{
		String url = pro.getProperty("url");
		String user = pro.getProperty("username");
		String password = pro.getProperty("password");
		//获取连接
		Connection conn = DriverManager.getConnection(url, user, password);
		return conn;
	}
	
	//释放资源/关闭连接
	public static void release(ResultSet rs,PreparedStatement pstm,Connection conn) throws Exception{
		if(rs!=null){
			rs.close();
		}
		if(pstm!=null){
			pstm.close();
		}
		if(conn!=null){
			conn.close();
		}
	}
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值