事务回滚点
一次性去执行多条(10000)sql语句的时候。一出现异常,10000条全部回滚。
如果出现的问题,设置一个回滚点,回滚到那一个点,就行了,这就避免全部回滚.
API
Savepoint sp = conn.setSavepoint() // 设置回滚点
conn.rollback(sp); //回滚到设置的点
conn.commit(); //回滚后必须提交
案例实现
需求:向数据库发送10000条数据,每1000条是合理的
/**
* @Auther: yanqi
* @Desc 向数据库发送10000条数据,每1000条做一个回滚点
*/
public class Demo2 {
@Test
public void test1(){
Connection conn = null;
PreparedStatement psmtm = null;
Savepoint sp = null;
try {
conn= JDBCUtil.getConnection();
String sql ="insert into t_user (username) values( ? )";
psmtm = conn.prepareStatement(sql);
//开启事务
conn.setAutoCommit(false);
for (int i = 1; i <1000 ; i++) {
if(i == 999){
int a = 1/0;
}
psmtm.setString(1,i+"江一燕");
psmtm.executeUpdate();
//每100条设置一个保存点
if(i%100 == 0){
sp = conn.setSavepoint();
}
}
//事务提交
conn.commit();
} catch (Exception e) { //这里一定要换成大的异常,小的异常,无法捕获;
//事务回滚
try {
conn.rollback(sp);//此时只回滚100条数据
conn.commit();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtil.close(psmtm,conn);
}
}
}
事务的特性ACID
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位(最小的一个整体),事务中的操作要么都发生,要么都不发生。
一组操作时一个整体。不能分割。
一致性(Consistency)
事务前后数据的完整性必须保持一致。 2000 1900
一致性和原子性相关。只有都成功或者,都失败(原子性) ,就可以保证事务的一致性。
事务的前后的内容一直。
转账: 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—异常。对上述没有任何影响了。
事务的隔离级别
如果不考虑事务的隔离性,将会产生以下问题:
由数据事务的并发造成的问题。
1、脏读,---最严重的事情 2、不可重复读 3、幻读(虚读)
脏读
一个事务读取了另外一个事务没有的提交的数据。非常严重。尽可能去避免掉脏读
不可重复读
一个事务读取另外一个提交过的数据。造成另外一个事务,多次读取的【内容】不一致,数据的内容的改变。 update
幻读(虚读)
一个事务读取另外一个事务已经提交的数据。但是这里面强调的数据数目的改变。insert,delete。
1、开始统计 100 用户下单 提交 2、查询 101
虚读和不可重复读
不可重复读: 同一条记录 内容的改变 --update
虚读: 条目数的改变---insert delete
数据库的事务隔离级别
数据库共定义了四种隔离级别:
Serializable:可避免脏读、不可重复读、虚读情况的发生。 (可串行化,一个事务一个事务运行)
Repeatable read:可避免脏读、不可重复读情况的发生。 (可重复读)【不可以避免虚读】
Read committed:可避免脏读情况发生。 (读已提交)【避免不了虚读以及不可重复读】
Read uncommitted:最低级别,以上情况均无法保证。 (读未提交)
设置事务的隔离级别
set session transaction isolation level 设置事务隔离级别 两个人
select @@tx_isolation 查询当前事务隔离级别
设置【读未提交】隔离级别
1、Read uncommitted (读未提交) 最低级别,以上情况均无法保证。 两个人的操作都是一样的
set session transaction isolation level Read uncommitted;
select @@tx_isolation;
start transaction;
update account set money = money-100 where name ='jack';
update account set money = money+100 where name ='rose';
rollback;
set session transaction isolation level Read uncommitted;
select @@tx_isolation;
start transaction;
select * from account;
设置【读已提交】隔离级别
2、Read committed;(读已提交) 可避免脏读情况发生(避免不了虚读以及不可重复读)
set session transaction isolation level Read committed;
select @@tx_isolation; -- 8.transaction_isolation
start transaction;
update account set money = money-100 where name ='jack';
update account set money = money+100 where name ='rose';
commit;
set session transaction isolation level Read committed;
select @@tx_isolation;
start transaction;
select * from account;
设置【可重复读】隔高级别
3、Repeatable read :可以避免脏读,不可重复度。
set session transaction isolation level Repeatable read;
select @@tx_isolation;
start transaction;
update account set money = money-100 where name ='jack';
update account set money = money+100 where name ='rose';
commit;
set session transaction isolation level Repeatable read;
select @@tx_isolation;
start transaction;
select * from account;
在mysql中。mysql数据库本身,对虚读已经进行了优化处理。所以展示不出虚读的发生。mysql处理的也不是特别好。
设置【可串行化】隔高级别
4:串行化的可以避免所有的问题。 数据库让其他的事务进行等待,等待一个事务结束之后,这个事务再去操作。
set session transaction isolation level Serializable;
select @@tx_isolation;
start transaction;
update account set money = money-100 where name ='jack';
update account set money = money+100 where name ='rose';
commit;
set session transaction isolation level Serializable;
select @@tx_isolation;
start transaction;
select * from account;
一个事务一事务的执行,只上一个事务结束了,另一个事务才可以操作,避免了所有问题
隔离级别的性能问题
性能比较
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;(读已提交)