这是有声音的视频, 请检查耳机或者音箱 声音输出设备
教程使用 Oracle 11g Release 2 版本
内容:介绍事务的四大特性(原子性,一致性,隔离性,永久性)和相应的例子来演示
===============================================
银行账号里的转账, 就是一个好的学习事务例子:
假设有2个账号, A账号和B账号 。
A 账号 转给 B 账号 100块钱,
(2个动作在里面, 1是A账号减去100块,2是B账号增加100块钱 ,2个动作不可分割-原子性)
如果当 B账号钱没有增加的时候, 那么A账号的钱不应该减少, 保持一致性。
CREATE TABLE zhang_hao( id integer, zhang_hu varchar(25), jin_e integer);
INSERT INTO zhang_hao VALUES(1,'A',1000);
INSERT INTO zhang_hao VALUES(2,'B',500);
COMMIT;
现在进行一个删除操作, 你会发现其实并不是真正的删除
用 scott 用户删除
SQL> DELETE FROM zhang_hao where id=2;
COMMIT; / ROLLBACK;
永久性 - 一旦commit提交了就不能回滚了,数据将真正写入到表中
====================================================
更新一条数据, 会出现2个用户同时更新的情况
SQL> show user;
USER is "SCOTT"
SQL> update zhang_hao set jin_e=300 where id=2;
解决并发一个办法:
当我在更新的时候 其他用户不能进行修改, 可以说是加上一个排它锁(隔离性)。
SELECT * FROM zhang_hao FOR UPDATE;
这样sys账号 就不能更新,在一个等待的状态中
UPDATE scott.zhang_hao SET jin_e=200 WHERE id=1;
==========================================================
ms sql sever中的begin....transaction控制事务的一致性,
在oracle中有 commit 和 exception , rollback
如果你想多条语句提交一起执行一起回滚.用savepoint
也就是说 多条语句中 , 任意一条出现错误都会导致全部语句不执行,回滚。
------------------------
下面一个完整的例子说明:
A账号转800块钱给B账号。
这就要注意一个问题, 当A账号的钱转出去了,中途出现错误,B账号没有收到。
这种情况我们就不应该减少A账号的钱, 不执行操作, 做一个回滚。
------------------------
下面代码演示上面所说的情况
先随便创建一张表
create table test( tt varchar(30) );
SQL> create or replace procedure zh_proc
2 as
3 begin
4 savepoint mystart;
5 update zhang_hao set jin_e=200 where zhang_hu='A';
6 insert into test values('dd');
7 update zhang_hao set jin_e=1300 where zhang_hu='B';
8 commit;
9 exception
10 when others then
11 rollback to mystart;
12 end;
13 /
也就是说:
5 update zhang_hao set jin_e=200 where zhang_hu='A';
6 insert into test values('dd');
7 update zhang_hao set jin_e=1300 where zhang_hu='B';
这3条语句任意一条出现执行错误, 都会回滚 rollback 到 开始的地方 mystart 。把3条语句看成一个整体。
删除 test 表
SQL> drop table test;
目的为了 执行 SQL> drop table test; 出现错误
SQL> execute zh_proc;
BEGIN zh_proc; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object SCOTT.ZH_PROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL> select * from zhang_hao;
ID ZHANG_HU JIN_E
---------- ------------------------- ----------
1 A 1000
2 B 500
可以证明 update zhang_hao set jin_e=200 where zhang_hu='A'; 这条语句被回滚了。
==========================================================
现在我们把test表新建回去
create table test( tt varchar(30) );
SQL> execute zh_proc;
PL/SQL procedure successfully completed.
SQL> select * from zhang_hao;
ID ZHANG_HU JIN_E
---------- ------------------------- ----------
1 A 200
2 B 1300
这样他就会成功提交执行那3条sql语句。
好了, 视频就到这里, 因为中途出现了一个连接上的问题, 视频就到这里结束了。 88