技术开发 频道

用Microsoft.net实现数据库事务(4)


【IT168技术文档】

  附A:事务简介
  一个事务是一系列动作作为单个逻辑单位来执行,这意味着这些动作要么全部成功,要么全部失败。如果最后一个动作失败了,那么以前的动作应该依次回滚,整个状态回到原先事务开始的状态。例如,有1000美圆从一个银行帐户扣除,转入另外一个帐户,那么事务保证两个事件只能一起成功,只要有一个失败,那么实际就不会发生任何动作,两个帐户没有发生任何改变,钱没有被存入和扣除。
  
  ACID属性
  
  有四个属性经常被用来描述事务:原子性(atomicity), 一致性(consistency), 隔离性(isolation), 持久性(durability)。在一个理想的环境里,事务符合这四个标准,但是一个事务的隔离级别是可以设置的,原因是设置一个事物的隔离级别为非常好的的“可序列化”会增加一种被称为“死锁“情况发生的机率。死锁是两个事务试图去锁住已经被对方锁住的资源,最后一个事务需要回滚,这样另外一个才得以继续。为了避免这样的情况发生,你要求降低一个事务的隔离级别来减低它的争夺力。
  
  ◆ 原子性:事务要作为一个原子单位工作,要不全部执行成功,要么全部失败
  ◆ 一致性:事务结束后需要保持所有数据的一致性,在一个关系数据库里,所有的规则要发生在事务引起的变动上,来保持数据的一致性,所有的内部数据结构,如B-tree索引、双向联结必须在事务结束后保持正确。
  ◆ 隔离性:并发事务所作出的变动必须和其他任何并发事务做的变更相隔离。一个事务要么看到其他事务更改它之前的数据,要么看到其他事务更改之后的数据,它不能看到临时的数据,。。。。。。
  ◆ 持久性:一个事务结束后,它的结果会持久地存在与系统中,它的变动甚至在系统瘫痪时候也会存在。
  
  事务支持级别

  对于Asp.net,页面的默认事务级别是“隔绝”,在企业级服务里面默认级别是“需要”,一般地,我们会在需要事务的第一层对象上设置级别为“需要”,被调用的对象设置为“支持”。这意味着顶层的对象会创建一个事务,每个被调用的对象被激活时,将进入这个事务的上下文中。
  
  事务隔离级别
  在一个程序中,依据事务的隔离级别将会有三种情况发生。
  
  ◆ 脏读:一个事务会读进还没有被另一个事务提交的数据,所以你会看到一些最后被另一个事务回滚掉的数据。
  ◆ 读值不可复现:一个事务读进一条记录,另一个事务更改了这条记录并提交完毕,这时候第一个事务再次读这条记录时,它已经改变了。
  ◆ 幻影读:一个事务用Where子句来检索一个表的数据,另一个事务插入一条新的记录,并且符合Where条件,这样,第一个事务用同一个where条件来检索数据后,就会多出一条记录。

  一个事务所选择的隔离级别影响着数据库怎样对待其他事务拥有的锁,你所选择的隔离级别依赖于你的系统和商务逻辑。例如,一个银行在客户取钱之前会检查它的帐户余额,这种情况下,就需要一个隔离级别为可序列化的事务,这样另外一个取钱动作在这次完成之前将不能执行。如果它们仅需要提供一个帐户余额,“读提交的“将是合适的级别,因为他们仅需要查询余额的值,级别的降低会使事务运行更快。
  
  附B 事务开发的建议
  ◆ 在一定负荷下面测试事务控制器来保证负荷下死锁不会发生
  ◆ 尽可能使用存储过程,它们在各种情况仍拥有最好的性能
  ◆ 企业级服务为事务的控制提供了一个高级的方式,但使用要谨慎,因为它使性能降低
  ◆ 分析你的系统,来决定使用哪一种隔离级别的事务。银行系统应该使用可序列化的隔离级别
  
  附C 监控事务
  没有一种特别的机制来追踪数据库事务和ADO.NET事务。
  
  ASP.NET和企业级服务的事务可以被控制台的组件服务程序来监控,组件服务在开始菜单的管理工具中可以找到。从这个工具中,你可以监控所有通过MS DTC来运行的事务,也就是ASP.NET和企业级服务的事务。你也可以监视事务的执行时间,甚至事务提交、回滚、取消的整个过程。
  
  附D 死锁
  当两个或两个以上进程(或线程)互相拥有对方需要的锁,就会发生死锁,一般是在数据库系统中,但也可能发生在任何的多线程程序中,比如:
0
相关文章