技术开发 频道

揭秘WebSphere中SCA组件的事务实现

4. 一个简单的实例

    下面我们通过一个简单例子,通过真正的代码调用轨迹来看SCA的事务是如何运作的。

    在上面的场景中,component1的事务需求是需要运行在全局事务中并且可以加入到已有的事务;component2则只能运行在自己的全局事务中;而component3则只能运行在本地事务中。具体配置如下:

    Stand-alone Reference的引用上面设置的事务限定符Suspend transaction为false。

    Component1接口上的事务限定符Join transaction为true。

    Component1实现上的事务限定符Transaction为Global。

    Component1到Component2上的事务限定符Suspend transaction为false。

    Component1到Component3上的事务限定符Suspend transaction为true。

    Component2接口上的事务限定符Join transaction为false。

    Component2实现上的事务限定符Transaction为Global。

    Component3接口上的事务限定符Join transaction为false。

    Component3实现上的事务限定符Transaction为Local。

    前面通过一个JSP来调用这个stand-alone reference,在各个component的实现中打印当前的Thread.currentThread().getStackTrace()。可以看到如下的输出:

    transactionRequiredActivitySessionNotSupported

    在component1实现的输出中,我们可以看到如下的EJB方法被调用到。这表示component1运行在一个全局事务中。

    下面是component2实现中的输出:

    transactionRequiredActivitySessionNotSupported
    transactionNotSupportedActivitySessionNotSupported
    transactionRequiredActivitySessionNotSupported

    可以看到有三次EJB调用。第一次是transactionRequiredActivitySessionNotSupported,这对应了对component2引用上的事务限定符为suspend transaction=false,表示调用时候需要把当前事务传播到下游的服务中。第二次是transactionNotSupportedActivitySessionNotSupported,表示挂起当前的事务,这对应了component2接口上面的jointransaction为false,第三次是重新启动一个新的全局事务transactionRequiredActivitySessionNotSupported,这对应了component2的实现上的事务限定符transaction为global。

    component3实现中的输出。

    transactionNotSupportedActivitySessionNotSupported
    transactionRequiredActivitySessionNotSupported

    这儿由于component1对component3引用上的事务限定符suspend transaction为false,所以这儿没有EJB调用(因为WAS默认会自动在当前线程上传播事务)。然后由于接口上声明不参加上游事务,所以产生了一次EJB调用,调用的方法是transactionRequiredActivitySessionNotSupported,从而为该SCA组件建立了一个新的事务;但由于该组件实现需要运行在本地事务中,因此再次发生EJB调用,方法是transactionNotSupportedActivitySessionNotSupported,在上面的EJB描述符中可以看到该方法对应的事务属性是NotSupported。

小结

    至此,我们可以得出如下的结论:

    1. WPS的SCA的事务实现时给予WAS的声明式事务。

    2. WPS通过一系列的消息处理器来实现不同的事务需求。

    由此我们可以得到当执行如下的服务调用时所经历的事务处理步骤为:

    Service service = ServiceManager.INSTANCE.locateService(referencename);
    String result = (String) service.invoke("target method name",parameters);

    1. 调用端SCA容器调用负责处理事务的消息处理器,该消息处理器根据引用上面定义的事务限定符决定是否需要调用EJB方法来挂起事务。

    2. 在结果一系列处理后消息被传递到服务提供端,然后SCA容器调用处理接口事务的消息处理器,消息处理器根据接口上定义的事务限定符决定是否要调用发起一次EJB调用来挂起当前的事务。

    3. SCA容器接着调用负责处理服务实现的事务处理器,该处理器根据实现上配置的事务限定符决定是否调用EJB方法来启动一个本地事务。

0
相关文章