一、数据库事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
二、事务的提交和产生
2.只有DML语句才会产生事务,其他语句不会产生事务。
3.commit/rollback/DDL语句都可以把当前事务给结束掉
4.commit和DDL语句结束事务的方式是把这个事务给提交了
5.rollback结束事务的方式是把这个事务给回滚了
注:
提交事务是指让这个事务里面的所有操作都生效到数据库中
回滚事务是指让这个事务里面的所有操作都撤销
三、对事务特性的测试
测试用的表:
create table t_customer(
id number,
name varchar2(20) constraint customer_name_nn not null,
constraint customer_id_pk primary key(id)
);
drop table t_customer
测试: 使用俩个终端窗口,同一个账号登录到数据库中,观察事务是否提交对用户查看数据的影响
注:一个用户对A表做了DML操作,但是没有提交事务,这时候别的用户是不能对A表再做其他的DML操作。(为了保证数据的安全和一致性)
例如1:
insert ....产生事务A
update ... 这个操作是事务A中的操作
insert .. 这个操作是事务A中的操作
commit; 让事务A里面的三个操作(insert,update,insert)生效、事务A结束
delete ... 产生新的事务B
insert .. 这个操作是事务B中的操作
insert .. 这个操作是事务B中的操作
insert .. 这个操作是事务B中的操作
rollback; 让事务B中的四个操作都撤销,事务B结束
如下面事务A的具体演示,是两个终端下的情况,右边的进行操作,而左边的进行检查,右边执行一步,左边检查一步,可以看出只有提交之后,数据库中其他用户才能够访问到:
如下是对事务B的具体演示,我们能够看到事务B的操作在执行过程到结束,对数据都没有造成更改,因为最后进行了rollback操作:
例如2:
insert ....产生事务Aupdate ... 这个操作是事务A中的操作
insert .. 这个操作是事务A中的操作
DDL语句; 事务A会被提交,事务A结束
rollback; 这时候回滚已经对事务A不起作用,因为事务A以及被提交了,当前已经没有事务了
如下图所示,当我们执行drop语句时,事务被自动提交,我们左边的窗口中查询到操作的结果(虽然drop语句操作失败,但照样提交事务)
注:create语句 drop语句 alter语句等都属于DDL语句
例3:回滚点/保存点 savepoint
例如:
DML语句1
savepoint A
DML语句2
savepoint B
DML语句3
rollback to A/B
这个时候可以通过这个回滚点让事务回滚到指定的位置,如果不指定回滚点而是直接rollback,那么事务会一下子回滚完.
【特别注意】:rollback到回滚点之后,这个事务并没结束,这个时候还可以接着回滚或者commit提交事务。
create table t_user(
id number primary key,
name varchar2(100),
salary number
);
drop table t_user;
例如:
insert into t_user values(1,'tom',1000);
savepoint A;
insert into t_user(id,name) values(2,'zs');
savepoint B;
delete from t_user;
rollback to B;
执行过程如下所示:
然后查询看结果
select * from t_user;
这就是设置保存点的作用,能够将数据回滚到你保存的地方,但是此时事务并没有完成,只有我们提交之后才能在另外一个终端中查看到
四、事务特征ACID:
原子性:Atomicity同时成功或者同时失败
一致性:Consistency
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:Isolation
事务操作应该相互独立
持久性:Durability
事务所做的影响 ,在事务结束之后应该能够是持久的。
4.1 isolation 事务隔离级别
事务中产生的问题:
1.脏读 主要针对update操作。 一个事务A读到另一个事务B中修改过但是还没有提交的数据
2.不可重复读 主要针对update操作。 一个事务A在第一次读数据和第二次读数据之间,有另一个事务B把这个数据更改并提交了,所以就出现了事务A里面读一个数据俩次,但是读到的结果是不同的。
3.幻读 主要针对的是insert/delete操作。事务A第一次用where条件筛选出了10条数据,事务A第二次用通样的where条件筛选出的却是11条数据,因为事务B在事务A的第一次和第二次查询之间进行了插入操作,并且插入的这个数据满足事务A的where筛选条件.
事务隔离级别有:
read-uncommitted 不提交也能读
read-committed 提交之后才能读 解决了脏读
repeatable-read 解决了脏读和不可重复读
serializable 三个问题都解决了
级别越高解决的问题越多但是效率越低。
注意:并不是所有数据库都支持这四种事务隔离级别,比如oracle就只支持第二种和第四种这俩种,比如mysql就四种全支持.
oracle里面默认的事务隔离级别是第二种:read-committed
oralce里面设置事务隔离级别:
Set Transaction Isolation Level Read Uncommitted
Set Transaction Isolation Level Read Committed
Set Transaction Isolation Level Read Repeatable
Set Transaction Isolation Level Serializable
参见:简单的事务处理问题