Transaction Attributes
事务特性
应用到实现服务组件对象类上的[Transaction]特性有五个不同的值,你可以通过TransactionOption枚举设定。TransactionOption枚举的这些值是Required、RequiresNew、Supported、NotSupported和Disabled。表7-1描述了这些值的含义。
表7-1 TransactionOption枚举
|
TransactionOption的值 |
描述 |
|
Required |
Required枚举标记了这个组件需要一个带事务的上下文。如果调用者的上下文中没有事务,则一个新的事务会在一个新的上下文中启动。如果调用者的上下文中已经存在一个事务,则和调用者一起使用同一个事务。 |
|
RequiresNew |
与枚举Required类似,使用RequiresNew的组件总是会存在于事务中。但是和Required不同的是,一个新的事务总是会被创建。这个事务总是和调用者可能已有的事务相独立。 |
|
Supported |
Supported枚举表示这个组件可以运行于带事务的上下文中,也可以没有。如果一个组件自己本身不需要事务,但可能会调用需要事务的组件,而且可能会被已经创建了事务的其他组件所调用的话,则这个枚举会很有用。Supported枚举让一个事务可以贯穿于多个组件,并且调用者和被调用者组件可以参与在同一个事务中。 |
|
NotSupported |
如果被标记为NotSupported,则这个组件永远都不会参与在事务中。如果调用者的上下文没有事务,则它可以运行在跟调用者相同的上下文中。如果调用者有一个带事务的上下文,则运行在一个新创建的不带事务的上下文中。 |
|
Disabled |
Disabled选项和NotSupported的区别在于,调用者上下文的事务会被忽略(而不是新创建一个不带事务的上下文)。 |
通过特性[Transaction]设定的这些事务选项的具体含义会被调用者的上下文所影响。表7-2有助于更好地理解这种行为。在这个表格里,所有五个事务选项根据调用者是
否参与事务的2个选项分开列出。第三列指示了该组件是否运行在事务中,第四列则指示了组件是否运行在一个新的事务中。
表7-2 TransactionOption行为
|
特性 |
调用者是否运行 在事务中 |
该组件是否运行 在事务中 |
是否运行在一个 新的事务中 |
|
Required |
Yes No |
Always |
No Yes |
|
Requires New |
Yes No |
Always |
Always |
|
Supported |
Yes No |
Yes No |
Never |
|
Not Supported |
Yes No |
Never |
Never |
|
Disabled |
Yes
No |
Yes, if calling context is shared No |
Never |
Supported or NotSupported
Supported还是NotSupported
经常有人问我:“为什么一个组件需要被标记为Supported来支持事务,而实际上这个组件本身并不需要事务支持呢?”
图7-4和7-5描述了为什么事务值Supported是一个有用的选项。在两个图中,三个对象都互相调用。在图7-4中,对象A的事务选项被设置为Required,由于客户端并不存在事务,所以一个新的事务被建立。对象B则被设置为NotSupported,对象C则又被设置为Required。由于对象B不支持事务,所以B所在的上下文没有事务相关联。当对象C被B调用时,则又有一个新的事务被创建。这样对象A和C所在的两个事务是完全独立的。对象C的事务可能被成功完成,而A的则可能被中止。

图7-4 中间对象事务特性设置为NotSupported的事务行为
图7-5显示了一个相似的情景,但是对象B的事务选项被设置为Supported。这样从对象A开始的事务会被传播到B和C。如果对象C的数据库操作失败了,则对象A上会进行回滚操作,因为这两个对象都运行在同一个事务中。

图7-5 中间对象事务特性设置为Supported的事务行为
Required or Requires New
Required还是RequiresNew
使用事务选项Required,如果调用者上下文没有事务则一个新的事务会被创建。如果调用者已经有了,则会参与同一个事务。而在有些情况下,却需要另一种行为。比如,如果图7-6中的对象A可以改变课程表,而对象B则需要把信息写入一个日志数据库。把信息写入日志的操作应该是独立于对象A的事务的。为了满足这种需求,对象B被标记为RequiresNew(总是需要一个新的事务)。

图7-6 设置为RequiresNew时的事务行为






