事务

# 事务?
--模拟银行转账问题

create table bank(
id number(6) primary key,
money number(6)check(money>0)
)
insert into bank values(1,100);
insert into bank values(2,100);


--转账步骤

--1给2转账50元(一起执行多条sql语句,每句之间用;隔开,并F5执行)
  update bank set money = money-50 where id=1;
  update bank set money = money+50 where id=2;


--发生错误的原因
--update语句违反约束余额>=0 第一个sql发生错误;第二个sql还在增加


***事务:是作为单个逻辑工作单元执行一系列操作***
***多个操作作为一个整体向系统提交,要么都执行,要么都不执行***
***事务是一个不可分割的工作逻辑单位***

--使用事务解决转账

begin
update bank set money = money-50 where id=1;
update bank set money = money+50 where id=2;
commit; --一起生
exception
when others then
rollback;--一起死
end;

***
# 事务四个特性:(ACID)
  原子性:要么都成功,要么都失败。
  一致性:当事务执行前后,总量保持一致。
  隔离性:各个事务并发执行时,彼此独立。
  持久性:持久化操作。

# 事务生命周期:
  MySQL:自动提交(将每条DML语句自动提交)
  Oracle:手动提交

事务的开始标识: 第一条DML

结束: 提交事务 撤销事务

a.提交
  i:显示提交:commit;
  ii:隐式提交:正常退出exit、DCL(grant...to..、revoke..from..)、DDL(create.../drop...)
b.撤销
  i:显示回滚:rollback;
  ii:隐式回滚:异常退出(宕机、断电)

保存点savepoint:
打游戏 10:1,2(savepoint),3,4,5,6,7,8,9
语法: x a b savepoint 保存点名字

create table xx(
id number(10) primary key,
name varchar2(10)
);
insert into xx values(1,'zs');
insert into xx values(2,'ls');
savepoint initdate;
insert into xx values(3,'ww');


select * from xx;
rollback to savepoint initdate;

 


--事务的隔离级别:多个事务会产合适生很多并发问题:
1.脏读:当一个事务正在访问数据,并对此数据进行修改(1――>2),但是这种修改【还没有提交到数据库(commit)】
此时,另一个事务也在访问这个数据。本质:某个事务(客户端)读取的数据是过时的。
2.不可重复读:在一个事务内(客户端)内,多次读取同一个数据,但结果不同。
本质:就是事务A拿到了 被其他事务B修改并体交后的数据。
3.幻读(虚读):在一个事务内(客户端)内,多次读取同一批数据,但结果不同。


不可重复读和幻读的区别:
a.不可重复读指的是对于"同一条"数据的查询操作 a――>b
幻读对于"多条数据"的查询操作,数据量数:20条――>18条

b.不可重复读:update
幻读:insert|delete

SQL99标准隔离级别 依次递进(解决并发效果,越来越稳定),但是性能越来越低。
并发性、可用性本身就是矛盾的。
  ---Read uncommitted 读未提交
  ---Read comitted 读已提交
  ---Repeatable 可重复读
  ---Serializable 序列化/串行化

Oracle支持: Read comitted 读已提交(默认)、Serializable 序列化/串行化、
(Oracle自身扩充了read only,实际read only 隶属于Serializable 序列化/串行化级别。)

---切换隔离级别:

commit;--结束前面的操作
set transaction isolation level Read Comitted;
set transaction isolation read only;


MySQL:全部支持
***
--事务三步走 (查询没有事务,只有DML有,增、删、改)
开始事务:从上一次事务结束之后,进行的第一次dml操作,就自动开启了事务
提交事务:commit;
回滚(撤销)事务:rollback;

 

insert into bank values(3,100);
insert into bank values(4,100);
insert into bank values(5,100);
rollback; --白玩,打回原形

 

--例子:办理学生离校手续

select * from grade where gradename = '白银'
select * from subject where gradeid=2
select * from result where subjectid in (5,6,7,8,9,10)

***查询result表中所有的”白银”阶段学生的考试成绩,保存到表HistoryResult中***

create table historyResult(
Id number(4)primary key,
StudentNo varchar2(50) not null,
SubjectId number(2) not null,
StudentResult number(4) null,
ExamDate date not null
)

--insert into tab1 select * from tab2;
insert into historyResult select * from result where subjectid in (5,6,7,8,9,10);
commit;

 

select * from historyResult;

 

***删除Result表中所有的“白银”阶段学生的考试成绩***

delete from result where subjectid in (5,6,7,8,9,10);
commit;


select * from historyResult;

 

posted @ 2020-07-23 22:05  弹弹大魔王  阅读(20)  评论(0)    收藏  举报