日期:2014-05-16  浏览次数:20397 次

Oracle的事务
显式调用
编写Oracle程序的时候,一个比较好的习惯就是要显示地执行Commit或者Rollback. 一些工具如Sqlplus在退出的时候,会自动commit,而另外一些则会rollback。 如果过分的依赖这些隐式地调用,那么有可能造成不可预估的后果。
?
SET TRANSACTION ? ?或者 ?DBMS_TRANSACTION 可以显示地开始一个事务, 但这不必要, Oracle在执行第一个修改语句的时候,会隐式开始一个事务。
?
SAVEPOINT: ?beforeDoTax
定义个mark point, 方便rollback到指定的位置。
?
?
COMMIT / ROLLBACK / ROlLBACK to beforeDoTax
提交或回滚到指定位置
?
在存储过程中,使用到COMMIT/ROLLBACK被认为是一个不是很好的编程实践,因为这个Commit和Rollback应该让调用者来实现,调用者才知道什么时候应该Commit和Rollback.
?
在Exception的处理中,如果只有WHEN OTHERS,而没有RAISE/RAISE_APPLICATION_ERROR,这一般被看成是一个Bug,因为他把原来的Exception悄无声息地忽略掉了。11g中如果没有RAISE,会产生一个编译的WARNING.
?
?
COMMIT 和 COMMIT WRITE NOWAIT
commit正常情况下是需要等待IO操作完成,修改写入redo日志才返回,这个期间用户在等待。这样就能确保即使硬件损坏,仍然能够让数据永久保存。
而commit wrie nowait的行为则是不需要等待IO完成,立刻返回,默认一定会写入redo日志。
?
nowait的用法比较特殊,一般情况下不能使用,不能为了提高性能而考虑使用nowait。特殊情况:
  • 某些时效性很强的数据,如证券交易,突然硬件坏掉,导致交易失败,这些数据不作处理是可以接受的。
  • 批处理的数据,用Flag列能够标识出哪些已经处理,哪些未处理,即使硬件坏掉后,再恢复的时候,也可以继续执行。
?
约束的验证是在执行完成之后
约束的验证是在SQL执行后,才进行验证的,而不是执行前,或者执行中
create table t(x init unique);
insert into t value (1);
insert into t value (2);
update t set x=x+1;?
如果是执行中验证,那么是有unique的问题,而执行完则没有。
?
?
透明分布式事务
Oracle使用DB Link能够在一个数据的Session中,直接使用其他数据库的表,并把这些对不同的数据库的操作归并到一个事务里面,可以依据需求进行Commit和Rollback,这样就把分布式数据库的事务处理透明化了
?
自治事务
pragma autonomous_transaction 极少数情况能够用到, 比较合理的是用在log里面,将log存入到table。即使归滚了,log方法里面的自治事务还是能够将log信息保存好。
?
事务编程中的不好的习惯
逐行提交
过程化的java/plsql编程语言很容易引入逐行提交,也就是在一个循环语句中进行了逐行commit. 通常的误区是认为这样commit的方式效率高, 或者认为没有足够的undo空间,比如看到了ORA_1555的错误。
?
逐行提交通常不会比一次性提交更快, 另外还需要考虑的一点是,如果过程实现了一般,然后失败了,如何继续的问题。一般会要引入新的代码来实现。 而如果是一次性提交则没有这个问题。
?
UNDO空间
这是必须的,没必要节省,需要保持在一个正常的范围。
?
?
不加conn.setAutoCommit(false)
如果代码不加这部分,多条update被自动commit,就有可能在异常发生时,丢失数据更新
?