oracle事务一致性:原子性

原子性

事务的动作要么一起成功,要么都不成功,这是事务的原子性。

原子性包括:

  1. 语句级原子性
  2. 过程级原子性
  3. 事务级原子性
  4. DDL与原子性

语句级原子性

如果某条语句(如insert、update)执行成功与否会自动控制事务。

如设置插入前的触发器。

create table t2(cnt int);

insert into t2 values(0);

commit;

create table t(x int check(x>0));

create trigger t_tragger
before insert or update on t for each row
begin
  if(inserting) then
                update t2 set cnt=cnt+1;
  else
    update t2 set cnt=cnt-1;
  end if;
  dbms_output.put_line('I fired and updateed '|| sql%rowcount||'rows');
  
  end;

由于 表t设置了值约束,当插入负数的时候,是不能插入的

insert into t values(1);

此时 表t2中的cnt=1

如果

insert into t values(-1);

会报ora-02290违反检查约束条件
在这里插入图片描述
此时去检查表t2的cnt值没有更新成2,仍然是1.

书《oracle编程艺术》中sqlserver需要显式执行触发器的回滚才能实现触发器的不执行,但是我测试的是可以的。

create table t1 (cnt int)

create table t (v int check(v>0))

create trigger t_tragger
on t
for insert
as 
begin
update t1 set cnt=cnt+1;
end


insert into t1 values(0)

select * from t1

insert into t values(-1)

过程级原子性

测试在存储过程中往表t中插入负数,会不会触发触发器的更新操作

create or replace procedure p
as 
begin
  insert into t values(1);
  insert into t values(-1);
  
  end;
  

当执行

begin
  p;
  end;

会报ora02290错误
在这里插入图片描述
表t 、t2不会插入和更新任何值

如果加入异常判断

  
begin
  p;
  exception
    when others then
      dbms_output.put_line('error'|| sqlerrm);
     -- raise_application_error(-20001,sqlerrm);
  end;

在when others then中
没有对错误抛出处理,只是进行了打印,
那么再执行时不会报错。
此时查询表t/t2会发现值被更新了一次。
这是因为存储过程中的每个Insert语句进行了事务提交,第二句sql因为不满足约束信息,跳转到when others then却没有执行异常处理,就回滚了。但是第一句sql没有回滚,被提交了。

begin
  p;
  exception
    when others then
      --dbms_output.put_line('error'|| sqlerrm);
     raise_application_error(-20001,sqlerrm);
  end;

在这里插入图片描述
这个时候保证了存储中必须全部执行完成后,才能提交事务。
所以在when others then 中必须加上raise 或者raise_application_error的处理,要不然语句的原子性会导致结果的提交,不能保证整个过程的原子性!

事务级原子性

一组SQL语句作为一个工作单元一同执行。数据库从一种一致状态转变为另一种一致状态。

DDL原子性

在oralce中执行DDL操作会导致事务的自动提交
尤其注意的是truncate table会导致事务提交。

但在sqlserver中可以在事务中创建临时表,不会导致事务提交。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值