2. SCA的事务模型
如下图所示,在SCA的世界中,一个SCA组件是由接口、服务实现和引用(可选)三个部分构成:

其中接口部分表示该组件能提供的业务能力;实现则是实现了该接口的组件;而引用则表示在服务实现中需要调用到的其他服务。
在事务方面,SCA通过在三个部分(接口、服务实现和引用)分别提供不同的限定符(qualifier)的方式来完成事务的定制。
接口部分的限定符有:
(1)Join Transaction:可以取值true或者false。这个限定符表示该组件是否愿意加入到调用方的事务中。
(2)Join Activity Session:可以取值true或者false。这个限定符表示该组件是否愿意加入到调用方的Activity session中。
实现部分的限定符有:
(1)Transaction:可以取值Global、Local或者Any。这个限定符表示该组件对运行环境的需求。global表示需要运行在一个全局事务中,这样SCA容器必须保证在调用该服务实现时总是有一个活动的全局事务。lobal则表示要运行在本地事务中。容器必须挂起当前活动的全局事务,并负责启动一个本地事务。any则表示该实现既可以运行在一个已有的全局事务中也可以运行在本地事务中。如果选择了any,容器如果发现当前没有活动的事务,就会建立一个本地事务。
(2)Activity session:可以取值true、false或者any。
引用部分的限定符有:
(1)Suspend transaction:取值为true或者false。用来表示在调用这个目标服务时是否需要把当前的全局事务挂起(但目标服务是否能加入到这个事务中还取决于目标服务的事务配置)。如果选择true,则表示当前服务的事务不会被传播给所调用的服务。这个限定符只针对同步调用有效。
(2)Suspend activity session:和suspend transaction类似,是否需要挂起当前的activity session。这个限定符只针对同步调用有效。
(3)Asynchronous invocation:取值为commit或者call。这是用来表示在通过异步的方式调用这个目标服务时,请求的JMS消息是否立即提交还是和当前的事务一起提交。当调用的目标服务时双向的请求时,这儿必须选择为commit,否则会造成死锁。
通过这三个部分的组合就可以实现细粒度的事务控制。可以看到SCA提供的事务描述比EJB的事务粒度更细。这样也就能对各个组件实现更为精确的事务控制。
下面具体给一个例子。
比如一个SCA组件有如下的事务需求:
(1)在运行时候需要有全局事务但不能加入到已有的全局事务中;
(2)该组件需要调用到其他的服务,希望其他的服务也能加入到自己的事务中。
那么在设计上:
(1)接口的事务限定符应该设置为join transaction=false,这样就防止了该组件加入到上游的事务中。
(2)实现上的事务限定符应该设置为transaction=global。这样SCA容器在调用该实现之前就会启动一个全局事务。
(3)引用上的事务限定符应该设置为suspend transaction=false。这样组件实现的事务就被允许传播到被调用的服务。