JDBC事务

本文介绍了JDBC事务的概念,以MySQL为例阐述了事务的管理,包括自动提交、手动开启和结束事务、回滚和提交操作。重点讲解了JDBC如何进行事务管理,通过Connection对象的setAutoCommit、rollback和commit方法实现事务控制。还提到了事务的ACID特性以及不同的事务隔离级别,讨论了脏读、不可重复读和幻读等问题及其在不同隔离级别下的表现。
摘要由CSDN通过智能技术生成

JDBC事务

1、什么是事务

1.1. 事务指的的逻辑上的一组(一组sql,insert update ,delete)操作,组成这组操作的各个单元(各个sql),要不全部成功,要么全部失败。

举例: 转账 a 给b 转账 100 a原来有1000 b原来也有1000
account 是一个表名 表示的 账务表,里面有人的信息,和人的金额。
update account set money=money-100 where name = a;
update account set money =money+100 where name=b;
假设:

update account set money=money-100 where name = a;
出现了异常。
update account set money =money+100 where name=b;

后果: a的余额是900 b的余额 1000

有了事务:

开启事务:
update account set money=money-100 where name = a;
出现了异常。 ---- 事务进行管理: 进行回滚: 更改的记录无效。
update account set money =money+100 where name=b;

此时:a的余额是1000 b的余额 1000

开启事务:
update account set money=money-100 where name = a;
update account set money =money+100 where name=b;
进行提交: 把更改的内容使之生效。

此时:a的余额是900 b的余额 1100

1.2. mysql中的事务管理
----mysql中,默认事务是自动提交的。一条sql一个事务。

开启事务
update
提交事务;

start transaction ---- 开启一个事务。以后的sql都在一个事务中。更改的内容不会自动提交。
rollback —事务的回滚—同时失败的情况。–事务结束,并且全部失败,数据回复到开始之前的状态
commit ----------事务的提交----同时成功—事务结束。全部成功。

----账务信息
create table account(
name varchar(10),
money double
);

insert into account(name,money) values(‘a’,1000);
insert into account(name,money) values(‘b’,1000);

去做a给b转100块。

-----mysql默认类似这样
start transaction ;
update account set money = money -100 where name = ‘a’;
commit;
start transaction ;
update account set money = money +100 where name = ‘b’;
commit;

----自身手动控制事务。
start transaction ;
update account set money = money -100 where name = ‘a’;

update account set money = money +100 where name = ‘b’;
commit;

1、事务的回滚
在这里插入图片描述

2、事务的提交
在这里插入图片描述

1.3. jdbc中事务管理----重点

JDBC的事务管理,通过Connection 对象来完成的事务管理。

在这里插入图片描述
void setAutoCommit(boolean autoCommit)
将此连接的自动提交模式设置为给定状态。

当我们传递的参数是 false的时候 相当于start transaction; 开启事务
当传递true的时候,自动提交。相当于一条sql语句一个事务。并且jdbc中。默认就是true。
开启事务:conn.setAutoCommit(false);

void rollback()
取消在当前事务中进行的所有更改
相当于rollback;表示的是事务结束。并且更改无效。把数据恢复到开启事务时候的状态。

void commit()
使所有上一次提交/回滚后进行的更改成为持久更改,
相当于commit 。表示事务的结束。并且数据更改有效

一旦数据commit之后,永久更改了。不能回滚了。

rollback 要放入到catch中。并且抓取异常的时候,尽可能抓取最大的(不是绝对)。
没有人为的控制事务的时候,情况

在这里插入图片描述
手动控制事务:

在这里插入图片描述

1.3.1. 事务回滚点
案例:
一次性去执行多条(10000)sql语句的时候。一出现异常,10000条全部回滚。
每100条是合理的。
insert into dept(id)
insert into employee()
100,到100的时候,财务部,所有的员工都加载进去。

101—200 加入java 研发部。
在这里插入图片描述

JDBC提供事务回滚点接口 Savepoint, 如果在事务中进行savepoint设置,可以在事务回滚时,回滚到指定回滚点

API:
Savepoint sp = conn.setSavepoint(); ----设置是的回滚点。
Savepoint
setSavepoint()
在当前事务中创建一个未命名的保存点 (savepoint),并返回表示它的新 Savepoint 对象。

Conn.rollback(sp);
void rollback(Savepoint savepoint)
取消所有设置给定 Savepoint 对象之后进行的更改。

把数据回滚到,指定的回滚点的位置。

Conn.commit(); //回滚后必须要提交

案例:向数据库发送10000条数据,每1000条是合理的。

@Test
public void dome(){
Connection conn = null;
PreparedStatement pstmt =null;
Savepoint sp = null;
try {
conn = JDBCUtil.getConnection();
//开启事务
String sql= “insert into tb_user (username) values(?)”;
pstmt = conn.prepareStatement(sql);
//开启事务
conn.setAutoCommit(false);//手动提交
//准备放10000
for(int i = 1;i<=10000;i++){

			if(i == 9527){
				int a = 1/0;
			}
			//设置值
			pstmt.setString(1, "u"+i);
			pstmt.executeUpdate();
			
			//每一1000设置回滚
			if(i%1000 == 0){
				sp = conn.setSavepoint();
			}
		}
		//正常执行之后,提交事务

conn.commit();
} catch (Exception e) {
e.printStackTrace();
try {
//出现错回滚点
conn.rollback(sp);
conn.commit();//回之前的数据一定要提交事务提交
} catch (SQLException e1) {
e1.printStackTrace();
}finally{
JDBCUtil.close(conn, pstmt);
}
}
}

  1. 事务的特性 ACID — 重点
    事务:一组操作。

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位(最小的一个整体),事务中的操作要么都发生,要么都不发生。

一组操作时一个整体。不能分割。

一致性(Consistency)
事务前后数据的完整性必须保持一致。
一致性和原子性相关。只有都成功或者,都失败(原子性) ,就可以保证事务的一致性。

事务的前后的内容一直。
转账: a 1000 b 1000 a给b转100;
转账之前 a和b的总额 2000
转账之后 也要2000;

隔离性(Isolation)
事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

多个事务是独立存在的。多个事物不能够相互干扰。

a –b—事务A

c-d—事务B

如果A失败了。不能够影响B

持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
a-100
b+100
提交
此时a永远少100
b永远的多了100

a – 100 a 900
b+100 b 1100
commit;

a -100 a 800
b+100 b 1200
rollback : a 900 b 1100

rollback—异常。对上述没有任何影响了。

2.1.1. 事务的隔离级别
如果不考虑事务的隔离性,将会产生以下问题:
由数据事务的并发造成的问题。

1、脏读,—最严重的事情。
2、不可重复读
3、幻读(虚读)
在这里插入图片描述
2.1.2. 脏读
一个事务读取了另外一个事务没有的提交的数据。非常严重。尽可能去避免掉脏读。

在这里插入图片描述
2.1.3. 不可重复读

在这里插入图片描述

一个事务读取另外一个提交过的数据。造成另外一个事务,多次读取的内容不一致,数据的内容的改变。 update

一个事务,读取了另外一个事务提交了的数据。-----同一行数据。
数据的改变。—update
在这里插入图片描述

2.1.4. 幻读(虚读)
虚读:一个事务读取另外一个事务已经提交的数据。但是这里面强调的数据数目的改变。insert,delete。

一个事务读取另外一个事务已经提交过的数据。 强调的是条目数的改变insert,delete

1、开始统计 100
用户下单 提交
2、查询 101

在这里插入图片描述

虚读和不可重复读
同一条记录 内容的改变 不可重复读–update
条目数的改变 虚读—insert delete
2.1.5. 数据库的事务隔离级别
数据库共定义了四种隔离级别:
Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化,一个事务一个事务运行)
Repeatable read:可避免脏读、不可重复读情况的发生。 (可重复读)【不可以避免虚读】
Read committed:可避免脏读情况发生。 (读已提交)【避免不了虚读以及不可重复读】
Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

设置事务的隔离级别
set session transaction isolation level 设置事务隔离级别 两个人
select @@tx_isolation 查询当前事务隔离级别

1、Read uncommitted 最低级别,以上情况均无法保证。

在这里插入图片描述
2、Read committed;可避免脏读情况发生(避免不了虚读以及不可重复读)
在这里插入图片描述

3、Repeatable read :可以避免脏读,不可重复度。不能避免虚度
在这里插入图片描述
在mysql中。mysql数据库本身,对虚读已经进行了优化处理。所以展示不出虚读的发生。

4:串行化的可以避免所有的问题。 数据库让其他的事务进行等待,等待一个事务结束之后,这个事务再去操作。

在这里插入图片描述
mysql默认的隔离级别: Repeatable–read
oracle 默认的隔离级别: Read committed

mysql中,对虚读(幻读) 进行了处理。避免虚读的发送。但是处理的结果不太满意。有时候还会发生。

2.1.6. 隔离级别的性能问题
性能比较
Serializable 性能最差:事务一个一个执行的。排队。

Serializable < Repeatable read < Read committed < Read uncommitted

安全性比较
Serializable 安全性最好:所有问题避免掉。

Serializable > Repeatable read > Read committed > Read uncommitted

Read uncommitted 避免不了最重问题,脏读。
Serializable:性能太差。

mysql (默认)-- Repeatable read;(可重复读)
oracle(默认) – Read committed;(读已提交)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值