信息系统的间的事务处理Java Connector Architecture (JCA) 1.5

 

信息系统的间的事务处理





整理者: freshlll@126.com

时间: 05年7月7月7日月7日7日


我尝试把这文章做了一个翻译,请大家多多指教,多多交流。


原文:


Importing Java Transactions from an External EIS Using JCA 1.5 Transaction Inflow

Date: Jul 1, 2005 By Madhusudhan Konda .



The introduction of inbound transactions in the Java Connector Architecture (JCA) 1.5 specification is a great step toward seamless integration of heterogeneous systems. Madhusudhan Konda explains the simple theory behind the transaction inflow contract and shows how easy it is to implement a resource adapter to import a transaction from an external enterprise.

Transactions are the backbone of enterprise systems, and the introduction of inbound transactions in the Java Connector Architecture (JCA) 1.5 specification is a great step toward seamless integration of heterogeneous systems. Transaction inflow contracts provide a mechanism for importing external transactional contexts, for transaction completion, and for crash recovery. But implementing these contracts is a complex and challenging task. This article explores the process of implementing contracts, explaining the contract in detail and designing a resource adapter capable of importing transacted messages originating from an external enterprise information system (EIS).This article has attempted to explain the transaction inflow, discussing the theory behind the inflow contract and implementing a resource adapter to import a transaction.

Introduction

Let's consider a travel company called MoonTravel, which has an in-house application called the Flight Reservation System (FRS). This system provides travel agencies with the capability of creating flight reservations, allowing travel agents to access MoonTravel's flight inventory in real time. MoonTravel doesn't intend to port this legacy application to the J2EE platform.

Recently, MoonTravel's Operations and Research departments have developed a revenue management system (RMS) that can vary ticket prices based on booking patterns coupled with geographic, seasonal, and other factors. The RMS is a semi-automated J2EE application that can add supplements to flight prices based on recommendations from the application's intelligence process. These recommendations are executed on a nightly basis. The RMS depends on the FRS for real-time booking feeds. Whenever a booking is confirmed, the FRS should update the RMS systems so that pointers to the booking patterns can be added to the RMS databases.

Integration of these two systems is a challenging task for MoonTravel's developers. A major requirement is to include external workflow in current transactions.

Whenever a travel agent confirms a booking, the FRS has a finite workflow:

  1. Add the order.

  2. Update the customer database and the order status.

  3. Update the agency revenue database.

  4. Update the flight inventory database.

  5. Bill the customer.

  6. Send a message to the RMS and update the operational database.

  7. Send a confirmation to the parties involved.

All of these tasks must be performed in a transaction. Step 6, sending a message to the RMS and updating the operational database, is the point where the two heterogeneous systems interact. That is, a legacy EIS stretches its transaction boundaries to the application server.

Until the advent of the Java Connector Architecture, there weren't any standards to transactionalize the workflow between disparate systems. Connector architecture has come a long way in developing standards for integrating the enterprise.

Sharing Transactions

Transaction inflow serves the purpose of injecting transactions from an EIS into the J2EE world. These transactions are initiated by the EIS. If a message arrived from the EIS in a transaction, the J2EE application should import the transaction context and perform the business process on that message in the same transaction. In MoonTravel's use case, the FRS asks the RMS to act on the booking message before it confirms the parties involved. If the RMS is unable to update its database for some reason, the transaction can be rolled back and retried later. In other words, each transaction is shared between the EIS and the J2EE worlds.

Importing the Transactions

It's easy to understand the procedures involved in importing transactions from an EIS. This is the task list:

  1. The EIS creates a transaction.

  2. The EIS sends a message along with a transactional context to the resource adapter. The transactional context can be specific to the EIS.

  3. The resource adapter extracts the EIS-specific transactional context into a standard javax.transaction.xa.Xid.

  4. The resource adapter creates an ExecutionContext with Xid and probably with an attribute to indicate the transaction timeout.

  5. The resource adapter submits the Work instance, coupled with the newly created ExecutionContext, to the application server.

  6. The application server reads the message and understands that the work is to be performed in a transaction. It enlists the Work instance in this imported transaction.

Upon the return of the Work instance, the EIS can commit the transaction either in a one-phase (1PC) manner or a two-phase (2PC) manner, the fundamental difference being that the 1PC doesn't need to call prepare before committing.

Following are the steps in a 2PC transaction:

  1. The EIS sends a prepare message to the resource adapter for the given transaction.

  2. The resource adapter calls prepare on an XATerminator obtained from BootstrapContext with Xid. It returns the result of the prepare call.

  3. Depending on the result, the EIS sends a commit or a rollback to the resource adapter.

  4. The resource adapter performs the commit or rollback.

The EIS can coordinate transactions with the resource adapter in many ways. For example, the transactional context, along with completion and recovery calls, can be published via a common messaging scheme between the EIS and the resource adapter. In a simple implementation, a business message produced by the EIS may contain Xid transaction-timeout attributes as message headers or properties. The resource adapter understands how to retrieve the transactional context from these properties. When a transaction is prepared for completion, the EIS sends a prepare message and the commit message for committing the transaction.

Now that we've explored the theory, let's delve into implementation details.

The Resource Adapter

The MoonTravel developers built an FRSResourceAdapter that acts a bridge between the RMS and the FRS, as shown in Listing 1. This resource adapter is bound to the J2EE application server's address space and acts on behalf of the FRS. The major requirement is to import the transaction that has been initialized by the EIS.

Listing 1 FRSResourceAdapter.java
public class FRSResourceAdapter implements ResourceAdapter {
    private XATerminator _xaTerminator = null;
    private WorkManager _workManager = null;

    public void start(BootstrapContext ctx){
      // get a reference to XATerminator and WorkManager
      xaTerminator = ctx.getXATerminator();
      _workManager = ctx.getWorkManager();
      ....
    }

    public void endpointActivation(MessageEndpointFactory endpointFactory,
       ActivationSpec spec) throws ResourceException {

    try {
      // Create a worker and submit for execution
      FRSWork worker = new FRSWork(spec, endpointFactory, _workManager, _xaTerminator);

      // Now schedule this worker
      _workManager.scheduleWork(worker);

    } catch (UnavailableException e) { .. }
  }
   ...
}

References to WorkManager and XATerminator are provided by the application server via BootstrapContext during the start method invocation. These objects are used to submit the work instances and complete the imported transactions, respectively. The XATerminator methods are invoked by the resource adapter, depending on the transactional attributes obtained from the EIS messages.

The Work Instance

A Work object is essentially a thread managed by the application server. The FRSWork shown in Listing 2 is instantiated and submitted to the application server for execution during the endpointActivation call.

Listing 2 FRSWork.java
public void FRSWork extends javax.resource.spi.Work {
    ...

    public FRSWork(ActivationSpec spec, MessageEndpointFactory listener,
        WorkManager workManager) throws UnavailableException{
       // Hold these references for the lifetime
       _xaSpec = (FRSActivationSpec) spec;
       _endpointFactory = endpointFactory;
       _workManager = workManager;}
    }
    ...
public void run() {
    while(ok){
      // This recv method consumes the messages incessantly
      msg = connection.recv();
    // Do the processing if a message is received
    try {
    //Check what kind of message it is
    if (msg instanceof PrepareSignal) {
      // EIS making a prepare call
      System.out.println(" PrepareSignal message");
      PrepareSignal psMsg = (PrepareSignal)msg;

      // We should convert EIS call to
      // our XATerminator's call

      int XA_RESULT = _xaTerminator.prepare((Xid)psMsg.getObjectProperty(FRS_XID));

      // Now that we have the result of prepare, we have to notify
      // EIS by sending a message from our RA

      notifyPrepareResultToEIS(psMsg, XA_RESULT);
    } else if (msg instanceof CommitSignal) {
      // EIS making a commit call
      System.out.println(" Commit Signal message");

      // The Boolean argument stands for
      // one-phase or two-phase commit
      CommitSignal commitMsg = (CommitSignal)msg;
      _xaTerminator.commit((Xid) commitMsg.getObjectProperty(FRS_XID), false);
    } else if (msg instanceof FRSMessage){
      // Business message, possibly in a transaction
      FRSMessage frsMsg = (FRSMessage) msg;

      // Create ExecutionContext from EIS Message. We are
      // expecting a transaction Xid and timeout if this
      // work is to be performed under a transaction
      execCtx = createExecutionContext(frsMsg);

      // Schedule for work with this ExecutionContext
      _workManager.scheduleWork(new TxWork(_endpointFactory, frsMsg),
           WorkManager.IMMEDIATE, execCtx, null);
    }
    } catch (Exception e) { .. }
    ...
  }

Pay attention to the FRSWork object's run method. When the application server executes FRSWork, it calls the run method, which checks for a message from the EIS by calling the recv method on FRSConnection. The recv method works incessantly to retrieve any messages via the Connection interface. In our simple implementation, the EIS can produce three kinds of messages, as shown in the following table.

Message

Description

PrepareSignal

Indicates that the transaction(n) with the Xid is ready to prepare. Upon receiving this message, the resource adapter calls the prepare call on XATerminator.

CommitSignal

Indicates that the transaction(n) with the Xid is to be committed. The resource adapter will now commit the transaction using XATerminator.

FRSMessage

Business message with a transaction Xid. The EIS expects to execute the message under the given transaction.

The ExecutionContext Object

The ExecutionContext provides a context in which the Work instance is to be executed. The resource adapter creates the ExecutionContext by extracting the transaction information from the FRSMessage, as shown in Listing 3.

Listing 3 Creating an ExecutionContext
public ExecutionContext createExecutionContext(FRSMessage msg)
    throws JMSException, NotSupportedException {

    // Get Xid and transaction timeout from message
    // FRS_XID and FRS_TX_TIMEOUT are the properties
    // set on this message by EIS
    Xid xid = (Xid) msg.getObjectProperty("FRS_XID");
    long txTimeOut = msg.getLongProperty("FRS_TX_TIMEOUT");

    // Create an ExecutionContext object with these values
    ExecutionContext execCtx = new ExecutionContext();
    execCtx.setXid(xid);
    execCtx.setTransactionTimeout(10000);

    return execCtx;
}

Whenever a Work instance is executed by the application server, an optional ExecutionContext can be provided. By default, a null ExecutionContext is provided, which indicates that the Work is not in a transaction. The transactional work is performed in the TxWork object, as shown in Listing 4.

Listing 4 The TxWork run Method
public void run() {
    try {
      // Create an endpoint listener. You can implement a
      // sophisticated MDBs pool here. For example, before creating
      // an endpoint, check whether one is available. If not available,
      // check the pool to grab one, etc.

      _endpointListener = (FRSListener)_endpointFactory.createEndpoint(null);

      // Now that we have the EIS message,
      // process it under the transaction
      _endpointListener.onMessage(_frsMsg);
    } catch (UnavailableException e) {
    ... 
    }
    ...
}

All the work performed in this run method is executed under the imported EIS transaction. From here on, the usual J2EE transaction concepts apply.

Transaction Completion

The EIS must send prepare/commit messages depending on the one-phase or two-phase commit criteria. The resource adapter calls prepare on the XATerminator instance by passing the transaction's Xid when it receives a prepare call. The result of the prepare call is passed back to the EIS via the notifyPrepareResultToEIS method, as shown in Listing 5.

Listing 5 Notifying the Prepare Result to EIS
private void notifyPrepareResultToEIS(EISMessage psSignal, int xa_result) {
    // Logic to inform the EIS about the prepare call
    // This uses the outbound connectivity for connecting to the EIS

    FRSConnection connection = FRSConnectionFactory.createConnection();
    PrepareSignalResult PREPARE_MESSAGE = new PrepareSignalResult(psSignal, xa_result);
    connection.sendPrepareMessage(PREPARE_MESSAGE);
    }
}

To send the prepare outcome, the resource adapter should get a connection to post a message to the EIS's inbound channel.

Once the outcome of the prepare call is received, the EIS decides whether to commit or roll back the transaction. The procedure is the same as that for prepare:

  1. The EIS sends a commit/rollback message with a transaction Xid.

  2. The resource adapter calls commit/rollback on the XATerminator object.

  3. XATerminator commits/rolls back the transaction marked with the Xid.

Crash Recovery

Any topic on transactions is incomplete without at least a mention of crash recovery, though implementation is beyond the scope of this article. The Java Connector Architecture allows room for implementation of recovery should your EIS or application server crash:

  • If an application server crashes during an active transaction (the transaction is not yet prepared), the EIS aborts the transaction. Similarly, if an EIS crashes with active transactions, the resource adapter aborts them.

  • If the application server goes down during an in-doubt transaction (the transaction is prepared but not yet committed), the EIS tries to reestablish communications with the application server and complete the transaction. If the EIS crashes during an in-doubt transaction, the resource adapter waits until the EIS is back online and tries to complete the transaction. The application server invokes the getXAResource(..) method when it's back from a crash, retrieving the XAResources allocated for the respective ActivationSpecs. It then calls recover for each XAResource obtained.

Summary

Importing external transactions from a different world into the J2EE platform can be difficult, but before the advent of JCA 1.5, this task was almost unthinkable. Transaction inflow has paved a way for injecting transactions from legacy systems such as CICS, SAP, and so on into a modern application hosted on a J2EE platform.

References




译文

译者:freshlll@126.com


整理:


JCA 1.5事务流(JCA 1.5 Transaction Inflow ,从外部EISenterprise information system)引入java 事务


Date: Jul 1, 2005 By Madhusudhan Konda .





Java Connector Architecture (JCA) 1.5 说明书中的外部进入内的事务的介绍,这对无缝的异构系统的集成是一个巨大进步。Madhusudhan Konda阐述:在事务流契约下一个简单的理论,并且怎样简单的实现一个适用于要从外部企业引入事务的资源。




事务是一个企业系统的枢纽,而Java Connector Architecture (JCA) 1.5 说明书中的外部进入内的事务的介绍,这对无缝的异构系统的集成是一个巨大进步。对事务完成,紧急故障恢复,引入外部事务,事务流契约提供了一个的机制。但是实现这些契约是一项复杂和挑战性的工作。这篇文章阐述了实现契约的过程,详细的解释了契约,并且设计 一个资源的实现,其能够传递来自外部企业信息系统消息。这篇文章也试着解释事务流,谈论在事务流下的理论和适应于引入事务流的资源的实现。



说明

让我们考虑一个叫(MoonTravel)的旅行公司,它有一个机票预定系统。这个系统为航空代理提供机票预定能力。它允许航空代理实时访问它的航班清单。 MoonTravel不打算吧这个应用程序布局到j2ee平台。

查:MoonTravel doesn't intend to port this legacy application to the J2EE platform.




最近 MoonTravel的运筹部开发了一个收入管理系统,它的订票模型能根据地理,季节和其它因素而改变票价。RMS是一个半自动的j2ee应用,它能基于智能程序的建议增补航班价格。这些建议被一个夜行平台执行。RMS依靠实时订票信息。无论什么时候订单确定,那么就会指示订票模型更新RMS数据库。

查:1.have developed a revenue management system (RMS)

2.These recommendations are executed on a nightly basis.

3.Whenever a booking is confirmed, the FRS should update the RMS systems so that pointers to the booking patterns can be added to the RMS databases.



moonTravel的开发者来说,集成这两个系统是一项挑战性的工作。一下主要的需要就是在当前事务中增加一个流程。

查:1.A major requirement is to include external workflow in current transactions.

无论什么时候一个航空代理确认了一个订单,FRS有一个固定流程。

1.添加订单

2.更新客户的数据库和订单状态。

3.更新代理的收入数据库。

4.更新航班清单数据库。

5.给客户帐单

6.法一个消息给RMS并且更新操作数据库。

7.发送信息给相关人员。





所以的工作都必须用事务来处理。第六步,发送一个消息给RMS并且更新操作数据库

,这是两个异构系统的交互点。这就是EIS把它的事务边界延伸到了应用服务器。

查:legacy 我看到有些经常用到这个词,比如legacy application,legacy EIS等。





还没有在不同的系统之间的事务流程处理标准,直到Java Connector Architecture的降临。Connector Architecture为企业集成带来了一个开发标准。



共享事务



事务流是为把事务从EIS注入到j2ee平台服务。这些事务由EIS发起,如果一个来自EIS的消息到来,j2ee应用就引入事务相关内容,并利用这个事务中消息处理相关的业务。

在确认相关的工作前FRS需要问RMS相关的订票的消息。这样如果RMS由于某些原因不能更新相关的数据库,相关的事务就能回滚或重做。换句话来说,每一个事务都是在EISj2ee平台之间共享的。







引入事务

EIS引入事务的处理过程是非常容易明白的。下面是工作列表:

1.EIS产生一个事务。

2.EIS发送一个带由事务内容的消息给资源适配器。事务内容对是EIS性质的。

查:The transactional context can be specific to the EIS.



3.资源适配器把EIS性质的事务内容转化为标准的javax.transaction.xa.Xid.

查:extract ......into ... extract :提取,摘录



4.资源适配器Xid产生一个ExecutionContext并且大概用一个属性指示事务超时。

5.资源适配器把附加上新的ExecutionContext的工作实例交给应用程序服务器。

6.应用程序服务器读取消息并且知道这个实例应是作为一个事务来处理。它运行这个引入进来的事务的实例。



在这个返回的实例下,EIS能够 one-phase manner1PC)或two-phase manner(2PC)的方式来提交事务,这两方式的不同之处在于(1PC)在提交前不用预编译。



2PC事务遵循以下步骤:

1.EIS为相关事务发出一个预编译的消息给资源适配器

2.资源适配器调用预编译产生一个于使用XidBootstrapContextXATerminator.它返回调用预编译结果。

3.依据这个结果,EIS发出提交或回退给资源适配器。

4.资源适配器处理这个提交或回退。



EIS有许多方式协同资源适配器处理处理事务。例如:完成或恢复的事务操作能够通过一个EIS和资源适配器的消息机制来处理。一个简单实现,由EIS产生的业务消息把包含Xid 事务超时属性作为消息头或属性。资源适配器知道怎样从事务中检索这些属性。当一个事务完成时,EIS发送一个预编译消息,为了提交事务的消息。





现在已经阐述了这个理论,让我们深入到实现细节。





资源适配器



MoonTravel 的开发者开发了一个作为RMSFES之间桥梁的FRSResourceAdapter,如下面的Listing 1.这个资源适配器被绑定到j2ee应用的地址空间并作为FRS的代理。一个主要的需求就是引入被EIS初始化的事务。







Listing 1 FRSResourceAdapter.java
public class FRSResourceAdapter implements ResourceAdapter {
    private XATerminator _xaTerminator = null;
    private WorkManager _workManager = null;

    public void start(BootstrapContext ctx){
      // get a reference to XATerminator and WorkManager
      xaTerminator = ctx.getXATerminator();
      _workManager = ctx.getWorkManager();
      ....
    }

    public void endpointActivation(MessageEndpointFactory endpointFactory,
       ActivationSpec spec) throws ResourceException {

    try {
      // Create a worker and submit for execution
      FRSWork worker = new FRSWork(spec, endpointFactory, _workManager, _xaTerminator);

      // Now schedule this worker
      _workManager.scheduleWork(worker);

    } catch (UnavailableException e) { .. }
  }
   ...
}



涉及到的WorkManager XATerminator是由应用服务器通过BootstrapContext,通过调用startf方法提供的,这些对象分别用于提交工作实例和完成引入的事务。资源适配器调,依据EIS消息上得到的事务属性,调用XATerminator方法。





工作实例



工作实例一个被应用服务器管理的必须的线程。在Listing2中展示的FRSWork,提交给应用程序服务器在endpointActivation 调用 中执行。







Listing 2 FRSWork.java
public void FRSWork extends javax.resource.spi.Work {
    ...

    public FRSWork(ActivationSpec spec, MessageEndpointFactory listener,
        WorkManager workManager) throws UnavailableException{
       // Hold these references for the lifetime
       _xaSpec = (FRSActivationSpec) spec;
       _endpointFactory = endpointFactory;
       _workManager = workManager;}
    }
    ...
public void run() {
    while(ok){
      // This recv method consumes the messages incessantly
      msg = connection.recv();
    // Do the processing if a message is received
    try {
    //Check what kind of message it is
    if (msg instanceof PrepareSignal) {
      // EIS making a prepare call
      System.out.println(" PrepareSignal message");
      PrepareSignal psMsg = (PrepareSignal)msg;

      // We should convert EIS call to
      // our XATerminator's call

      int XA_RESULT = _xaTerminator.prepare((Xid)psMsg.getObjectProperty(FRS_XID));

      // Now that we have the result of prepare, we have to notify
      // EIS by sending a message from our RA

      notifyPrepareResultToEIS(psMsg, XA_RESULT);
    } else if (msg instanceof CommitSignal) {
      // EIS making a commit call
      System.out.println(" Commit Signal message");

      // The Boolean argument stands for
      // one-phase or two-phase commit
      CommitSignal commitMsg = (CommitSignal)msg;
      _xaTerminator.commit((Xid) commitMsg.getObjectProperty(FRS_XID), false);
    } else if (msg instanceof FRSMessage){
      // Business message, possibly in a transaction
      FRSMessage frsMsg = (FRSMessage) msg;

      // Create ExecutionContext from EIS Message. We are
      // expecting a transaction Xid and timeout if this
      // work is to be performed under a transaction
      execCtx = createExecutionContext(frsMsg);

      // Schedule for work with this ExecutionContext
      _workManager.scheduleWork(new TxWork(_endpointFactory, frsMsg),
           WorkManager.IMMEDIATE, execCtx, null);
    }
    } catch (Exception e) { .. }
    ...
  }





注意FRSWorkrun 方法,当应用服务器执行FRSWork,它调用run方法,这个方法检查EISFRSConnection 调用recv 方法而得到的消息。Recv方法通过连接接口不间断的回收任何消息。在我们简单实现中,EIS能产生三种消息,在下面的表中可以看到。



Message



Description

PrepareSignal

指的是Xid事务已经准备,利用接受的消息, 资源适配器调用基于XATerminator的预编译的调用。

CommitSignal

指的是Xid事务被提交,资源适配器将用XATerminator提交事务。

FRSMessage

带有Xid事务的业务消息,EIS期望执行在给出的事务下的消息







The ExecutionContext Object

ExecutionContext 提供 让工作实例执行一个上下文环境,资源适配器通过从FRSMessage提取的事务信息中产生 ExecutionContext。如Listing3所示。





Listing 3 Creating an ExecutionContext
public ExecutionContext createExecutionContext(FRSMessage msg)
    throws JMSException, NotSupportedException {

    // Get Xid and transaction timeout from message
    // FRS_XID and FRS_TX_TIMEOUT are the properties
    // set on this message by EIS
    Xid xid = (Xid) msg.getObjectProperty("FRS_XID");
    long txTimeOut = msg.getLongProperty("FRS_TX_TIMEOUT");

    // Create an ExecutionContext object with these values
    ExecutionContext execCtx = new ExecutionContext();
    execCtx.setXid(xid);
    execCtx.setTransactionTimeout(10000);

    return execCtx;
}

无论什么时候资源工作实例被应用程序服务器执行,一个可选的ExecutionContext被提供,默认的情况下,一个空的ExecutionContext被提供,指的是工作实例不在事务中。事务工作在TxWork中处理,如Listing4所示。





Listing 4 The TxWork run Method
public void run() {
    try {
      // Create an endpoint listener. You can implement a
      // sophisticated MDBs pool here. For example, before creating
      // an endpoint, check whether one is available. If not available,
      // check the pool to grab one, etc.

      _endpointListener = (FRSListener)_endpointFactory.createEndpoint(null);

      // Now that we have the EIS message,
      // process it under the transaction
      _endpointListener.onMessage(_frsMsg);
    } catch (UnavailableException e) {
    ... 
    }
    ...
}



引入的EIS事务下所有的工作都被run方法执行。在这里,通常的j2ee事务概念实行。







Transaction Completion

依据 one-phase two-phase 提交准则,EIS必须发送 预编译/提交 消息。资源适配器通过Xid 事务调用预编译,当它接受到一个预编译的调用。预编译的调用结果通过notifyPrepareResultToEIS方法传回EIS.Listing5所示。





Listing 5 Notifying the Prepare Result to EIS
private void notifyPrepareResultToEIS(EISMessage psSignal, int xa_result) {
    // Logic to inform the EIS about the prepare call
    // This uses the outbound connectivity for connecting to the EIS

    FRSConnection connection = FRSConnectionFactory.createConnection();
    PrepareSignalResult PREPARE_MESSAGE = new PrepareSignalResult(psSignal, xa_result);
    connection.sendPrepareMessage(PREPARE_MESSAGE);
    }
}



为了发送预编译结果,资源适配器得获得一个连接以发送一个消息给EIS的边界通道。



一旦预编译调用的结果被接收,EIS将决定是否提交或回退事务。这个过程和预编译一样:

1.EISXid事务发送一个 提交/回退 的消息。

2.资源适配器在XATerminator 对象上调用 提交/回退 操作。

3.XATerminator 对象提交/ 回退 标记Xid 的事务。



紧急故障恢复



任何关于事务的话题不能没有至少一个紧急故障恢复的涉及,虽然实现超出了这篇文章的范围。Java Connector Architecture 提供为EIS 应用服务器故障 实现故障恢复的空间。



.如果在一个应用服务器在启动的事务(没有预编译的事务)中发生故障,EIS将中止这个事务。同样的,如果EIS在启动事务发生故障,资源适配器将中止它。

.如果一个应用服务在一个不确定的事务(事务已经准备好了但是没有提交)中下降,EIS将试着和应用服务建立联系并且完成这个事务。如果EIS事故在一个不确定事务中产生,

资源适配器等到EIS返回并且试着完成这个事务。应用服务调用 getXAResource(..) 方法当它从一个故障中恢复,检索为各自的ActivationSpecs 分配的XAResources.然后它将为每个XAResource获得的调用恢复工作。



小节

从一个不同平台引入一个额外的事务到j2ee平台很困难,在JCA1.5的到来之前,这种工作几乎不可能想象。事务流程已经为注入事务从现有的系统比如 CICS,SAP等等到现代的j2ee应用平台铺平了一条道路。





参考






---------------------------------------------------------------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息认证通常指的是验证数据的完整性、真实性和可信度,Java提供了多种实现方式,以下是其中的一种: 1. 使用数字签名进行信息认证 数字签名是一种数字证书技术,用于验证消息的完整性和真实性。在Java中,可以使用Java Cryptography Architecture (JCA)提供的API实现数字签名。具体步骤如下: - 生成密钥对:使用KeyPairGenerator类生成公钥和私钥。 - 签名:使用Signature类对消息进行签名,其中需要使用私钥对消息进行加密。 - 验证:使用Signature类对签名和消息进行验证,其中需要使用公钥对签名进行解密。 以下是Java代码示例: ```java import java.security.*; public class SignatureExample { public static void main(String args[]) throws Exception { // Generate key pair KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA"); keyGenerator.initialize(2048); KeyPair keyPair = keyGenerator.genKeyPair(); // Sign message Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(keyPair.getPrivate()); byte[] message = "Hello, world!".getBytes(); signature.update(message); byte[] digitalSignature = signature.sign(); // Verify signature signature.initVerify(keyPair.getPublic()); signature.update(message); boolean verified = signature.verify(digitalSignature); System.out.println("Message verified: " + verified); } } ``` 注意:以上代码只是一个简单的示例,实际使用时需要更加谨慎地处理密钥和签名,以确保信息的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值