`
liwenshui322
  • 浏览: 512419 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Oracle事务浅谈

 
阅读更多

     数据库引入事务的主要目的是:事务会把数据库从一种一致状态转变为另一种一致状态。在数据库中提交工作时,可以确保要么所有修改都已经保存,要么所有修改都不保存。另外,还能保证实现了保护数据完整性的各种规则和检查。

 

     这对于我们的一些应用是至关重要的,比如一个转账业务,从A账户转出1000元到B账户,操作1:从A账户减少1000元,操作2:B账户增加1000元。假如不能保证这两个操作要么都成功,要么都失败,就会有问题的。比如操作1成功了,操作2失败了。那么客户应该把你告上法庭了。

     事务都有四个特征:

     原子性(atomicity):事务中的所有动作要么都发生,要么都不发生。

     一致性(consistency):事务将数据库从一种一致状态转变为下一种一致状态。

     隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。

     持久性(durability):事务一旦提交,其结果就是永久性的。

 

     oracle通过读一致性版本保证了一致性与隔离性。下面我们看看oracle如何实现原子性。

    

     1. 语句级别原子性

     假设一条插入语句I1影响了T1表,同时触发了触发器,触发器影响了T2表。那么假设这条插入语句失败,对T1与T2的影响都会回滚。但是在Sql Server里面,触发器会独立于触发语句执行。如果触发器遇到一个错误,它必须显式 地回滚自己的工作,然后产生另外一个错误来回滚触发语句。否则,即使触发语句(或该语句的另外某个部分)最终会失败,触发器完成的工作也会持久保留。

 

     2. 过程级别原子性

     假设一个存储过程执行2哥插入操作I1与I2,都影响T1表,同时插入操作会触发触发器,触发器影响T2表。那么假设I1执行成功,I2执行失败。那么对T1与T2表的影响都会回滚。

     3. 事务级别原子性

     最后,还有一种事务级原子性的概念。事务(也就是一组SQL语句作为一个工作单元一同执行)的总目标是把数据库从一种一致状态转变为另一种一致状态。

        为了实现这个目标,事务也是原子性的,事务完成的所有工作要么完全提交并成为永久性的,要么会回滚并撤销。像语句一样,事务是一个原子性的工作单元。提交一个事务后,接收到数据库返回的“成功”信息后,你就能知道事务完成的所有工作都已经成为永久性的。

 

     最后说2种不好的事务习惯。

     1. 再循环中提交事务

      如果交给你一个任务,要求更新多行,大多数程序员都会力图找出一种过程性方法,通过循环来完成这个任务,这样就能提交多行。据我听到的,这样做的两个主要原因是:

      A. 频繁地提交大量小事务比处理和提交一个大事务更快,也更高效。

      B. 没有足够的undo空间。

      这 两个结论都存在误导性。另外,如果提交得太过频繁,很容易让你陷入危险,倘若更新做到一半的时候失败了,这会使你的数据库处于一种“未知”的状态。要编写 一个过程从而在出现失败的情况下能平滑地重启动,这需要复杂的逻辑。到目前为止,最好的方法是按业务过程的要求以适当的频度提交,并且相应地设置undo段大小。

      如果在循环中提交事务,可能会遇到让人胆战心惊的ORA-01555错误(snapshot too old)。这是因为如果是一个大批次的更新操作,这些操作会先读取要更新的数据进行“拍照”。其实这些照片是存放在undo段的,每更新一行都会去undo段取对应的“照片”,但是如果一边更新与提交,这些更新信息也会写入undo段。假设undo段不大的话,以前的“照片”可能就会被这些更新信息覆盖掉。这样如果找不到照片就会报这个错误了。

并且最严重的是,报这个错误的时候,你甚至没有办法进行恢复。因为报ORA-01555错误的例子会使更新处于一种完全未知的状态。有些工作已经做了,而有些还没有做。已经做的工作提交了,无法进行回滚。那么我们只能把那些没做的工作拿出来继续完成,遗憾的是我们无法区分那些工作是没做的。

 

    2. 自动提交事务

    在我们用jdbc获取一个连接执行sql语句的时候,没执行一条sql语句默认提交一遍事务。其实这是错误的做法。我们需要在获取到jdbc连击之后conn.setAutoCommit (false);将自动提交关闭。

    

 

 

    

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics