제2장 예제

내용 목차

2.1. Inbound 예제
2.1.1. 환경설정
2.1.2. 서버 시작
2.1.3. 서비스 요청
2.2. Outbound 예제
2.2.1. 환경설정
2.2.2. 클라이언트 프로그램
2.2.3. 주요 기능

본 장에서는 WebtAsync의 Inbound/Outbound 예제에 대해 기술한다.

2.1. Inbound 예제

2.1.1. 환경설정

Inbound 서비스를 사용하기 위해서 Tmax와 JTmaxNServer에 대한 환경설정을 해야한다.

Tmax 환경설정

GATEWAY 설정에서 GWTYPE만 “JEUS_ASYNC”이고, 그 외 설정은 기존의 Java 게이트웨이와 동일하다.

*SERVICE
ECHO_STRING SVRNAME=javagwa

*GATEWAY
javagwa GWTYPE=JEUS_ASYNC,
        NODENAME=tmax,
        PORTNO=8550,
        RGWADDR="192.168.11.240",
        RGWPORTNO=8282,
        CLOPT="-r"

Inbound에 필요한 설정은 GWTYPE=JEUS_ASYNC, RGWADDR="192.168.11.240", RGWPORTNO=8282 이다. RGWADDR, RGWPORTNO는 JTmaxNServer로 접속할 IP와 포트 번호이다.

Tmax가 부팅하는 경우 JTmaxNServer와 maxchl * cpc 개수만큼 연결이 맺어진다.

JTmaxNServer 환경설정

JTmaxNServer의 환경설정은 JTmaxNServer가 WebLogic 서버에서 기동되는 것을 기준으로 설명하도록 한다. Sample JTmaxNServer 기동을 위해서 WebLogic 서버에 JTmaxNServer 애플리케이션을 ear 형태로 배포한다.

Sample 애플리케이션인 TmaxInboundEApplication.ear 내에는 JTmaxServer를 기동 및 종료를 위한 구현체와 메시지 처리를 위한 JTmaxNJGMessageHandler 구현체가 포함되어 있다.

  • TmaxInboundEApplication.ear /META-INF/weblogic-application.xml 설정

    WebLogic 서버를 부팅하는 경우 JTmaxNServer를 기동하여 "/META-INF" 내에 weblogic-application.xml에 다음과 같이 설정한다.

    TmaxServerLifeCycle 클래스는 WebLogic에서 제공하는 ApplicationLifecycleListener를 상속받아 구현하도록 한다.

    <?xml version="1.0" encoding="UTF-8"?>
    <weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
    <listener>
            <listener-class>com.tmax.inbound.TmaxServerLifeCycle
            </listener-class>
            <listener-uri>TmaxInboundEApplicationEJB.jar</listener-uri>
    </listener>
    </weblogic-application>
  • webt.properties 설정

    JTmaxNServer 내에서 WebT API를 사용할 경우 로그를 남기거나, FDL을 사용하기 위해서는 webt.properties에 위와 같이 설정을 하고 WebLogic 서버를 기동하는 경우 "-Dwebt.properties= 절대경로"로 설정한다.

    log.level=debug
    log.dir=D:\\tmax
    log.file=tmax_webt.log
    fdl.file=D:\\tmax\\tmax.fdl
  • com.tmax.inbound.properties 설정

    JTmaxNServer 기동을 위한 기본 설정과 메시지 처리를 위해 필요한 EJB 설정을 위한 파일이다.

    다음 설정은 ECHOSTRING 이라는 서비스가 호출되면 echo EJB의 echoString 메소드가 호출하는 방식으로 동작한다. 이 설정 파일은 Sample JTmaxNServer를 위한 설정 파일로 반드시 필요한 파일이 아니며, 다른 방식으로 얼마든지 구현이 가능한 부분이다.

    ejb.names=ejb1
    ejb1.exportname=Echo
    ejb1.methodname=echoString
    ejb1.tmax.servicename=ECHO_STRING
    tmax.inbound.servers=jtmax1
    jtmax1.listen.port=8282
    jtmax1.worker.thread.max = 20
    jtmax1.worker.connection.max = 50 

2.1.2. 서버 시작

Tmax로부터 오는 서비스 요청을 처리하기 위한 JTmaxNServer를 JTmaxNServerImpl로 서버 객체를 생성한다.

JTmaxNServer를 생성할 때 서비스 처리를 위한 callback 인터페이스인 JTmaxNJGMessageHandler를 구현한 구현체를 인자로 설정해야 한다. listening port로 소켓을 열어 요청을 기다리게 되며 이때 Acceptor 스레드를 생성하게 된다.

JTmaxNServer server = new JTmaxNServerImpl(“JTmaxNServer1”, 8881,100, 50, 
                      new WebLogicJTmaxNJGMessageHandler());
server.startServer(); 

다음은 JTmaxNServerImpl의 생성자 API에 대한 설명이다.

JTmaxServerImpl(String serverName, int port, int connection, int thread,
                JTmaxNJGMessageHandler handler)
항목설명
serverNameJTmaxNServer 이름이다.
portlistening port number 이다.
connection허용 가능한 connectin 수이다.
thread메시지를 수신할 때 callback 호출할 사용자 스레드 수이다.
handler메시지 처리 Handler이다.

2.1.3. 서비스 요청

Tmax 클라이언트 서비스 요청

Tmax 클라이언트에서는 Tmax에 있는 서비스를 호출하는 것과 동일하게 서비스를 요청한다. 서비스 로직 처리 이후에 serviceHandler.serviceFinished() 함수를 호출하면 Tmax 서버로 결과를 보내게 된다.

...
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
        printf("sndbuf alloc failed !\n");
        tpend();
        exit(1);
}
cd = tpacall("ECHO_STRING", sndbuf, 0, 0);
...

JTmaxNServer에 서비스 요청

Tmax 서버가 클라이언트로부터 서비스 요청을 받은 후 Async Java 게이트웨이를 통하여 JTmaxNServer에게 해당 서비스를 요청한다. JTmaxNServer가 요청을 받으면 JTmaxNJGMessageHandler의 serviceExecute가 호출된다. 개발자는 serviceExecute 메소드에서 serviceName에 해당하는 서비스 처리 로직을 구현하면 된다.

...
public void serviceExecute(int sessionId, Xid xid, String serviceName, 
                        WebtBuffer receiveBuffer, JTmaxNServiceHandler
                        serviceHandler) {
        // 서비스 처리 로직 부분
        EchoHome home = (EchoHome) PortableRemoteObject.narrow(objref,
                                                          EchoHome.class);
        Echo echo = home.create();
        String value = echo.echoString(receiveBuffer.getString());
        WebtBuffer sendBuffer = new WebtStringBuffer();
        sendBuffer.setString(value);
        if (serviceHandler != null) {
                serviceHandler.serviceFinished
                (JTmaxNServiceHandler.TPSUCCESS,EJB_SVC_SUCCESS, sendBuffer);
        }
}
...

EJBCallWorker, XACommitWorker, XAPrepareWorker, XARollbackWorker는 서비스 처리를 위해 작성한 사용자 스레드 클래스이다.

public class WebLogicJTmaxNJGMessageHandler implements
        JTmaxNJGMessageHandler {
             public WebLogicJTmaxNJGMessageHandler () {
        }
        private XAResource getXAResource() {
             return TxHelper.getServerInterposedTransactionManager().getXAResource();
        }
        public void bulkRecover(Xid[] xids) throws NotSupportedException {
             if (xids == null) {
             return;
             }
             TmaxXid tmaxXid = null;
             for (int i = 0; i < xids.length; i++) {
                     tmaxXid = (TmaxXid) xids[i];
                     int decision = tmaxXid.getDecision();
                     switch (decision) {
                     case tmax.webt.io.Webt.TM_XA_COMMIT:
                     case tmax.webt.io.Webt.TM_XA_COMMIT2:
                             xaCommit(-1, xids[i], false, null);
                             break;
                     case tmax.webt.io.Webt.TM_XA_RBACK:
                     case tmax.webt.io.Webt.TM_XA_RBACK2:
                             xaRollback(-1, xids[i], null);
                             break;
                     default:
                     break;
                     }
             }
        }
        public void closeSession(int sessionId) {
             System.out.println("closed sessionId = " + sessionId);
        }
        public void closeTrunk(TmaxAliveInfo info) {
             for (int i = 0; i < info.getTrunkSize(); i++) {
                Hashtable<Integer, String> table = info.getTrunk(i);
                Iterator<Integer> it = table.keySet().iterator();
                while (it.hasNext()) {
                    Integer key = (Integer) (it.next());
                    String ip = (String) (table.get(key));
                    System.out.println("client index = " + key +", ip = " + ip);
                }
             }
        }
        public Xid[] recover() {
             Xid[] xids = null;
             try {
                     xids = getXAResource().recover(XAResource.TMSTARTRSCAN);
             } catch (XAException e) {
                     e.printStackTrace();
                     return null;
             }
              return xids;
        }
        public void serviceExecute(int sessionId, String serviceName, 
        WebtBuffer receiveBuffer) {
                        new Thread(new EjbCallWorker(sessionId, serviceName,
                                   receiveBuffer)).start();
        }
        public void serviceExecute(int sessionId, Xid xid, String serviceName,
                                   WebtBuffer receiveBuffer, JTmaxNServiceHandler
        serviceHandler) {
                new Thread(new EjbCallWorker(sessionId, xid, serviceName,
                           receiveBuffer, serviceHandler)).start();
        }
        public void xaCommit(int sessionId, Xid xid, boolean onePhrase,
                             JTmaxNServiceHandler serviceHandler) {
                new Thread(new XACommitWorker(sessionId, xid, onePhrase, 
                           serviceHandler)).start();
        }
        public void xaPrepare(int sessionId, Xid xid, 
                              JTmaxNServiceHandler serviceHandler) {
                new Thread(new XAPrepareWorker(sessionId, xid, 
                           serviceHandler)).start();
        }
        public void xaRollback(int sessionId, Xid xid, 
                               JTmaxNServiceHandler serviceHandler) {
                new Thread(new XARollbackWorker(sessionId, xid, 
                           serviceHandler)).start();
        }
}

참고

관련 API의 자세한 정보는 WebtAsync 2.0.0.0 API를 참고한다.

2.2. Outbound 예제

2.2.1. 환경설정

Outbound 서비스를 사용하기 위해서 Tmax에 대한 환경설정을 해야한다.

Tmax 환경설정

Tmax 환경설정 파일에 GATEWAY 설정에서 GWTYPE만 “JEUS_ASYNC” 이고 그 외의 설정은 모두 기존의 Java 게이트웨이와 동일하다.

*SERVICE
TOUPPER SVRNAME=svr2a

*GATEWAY
javagwa GWTYPE=JEUS_ASYNC,
NODENAME=tmax,
PORTNO=8550,
RGWADDR="192.168.11.240",
RGWPORTNO=8282,
CLOPT="-r"

Outbound에 필요한 설정은 GWTYPE=JEUS_ASYNC, PORTNO=8550 이다. PORTNO는 WebtAsync 애플리케이션으로부터 접속 요청을 받을 포트 번호이다.

2.2.2. 클라이언트 프로그램

tpcall 예제

Tmax의 Async Java 게이트웨이와 접속하기 위한 WebtEndpoint 객체를 생성하고 접속 정보 및 기타 설정을 한다. WebtEndpoint로 Async Java 게이트웨이에 연결할 수 있는 Connection 수는 GATEWAY 절에 MAXINRGW 항목으로 설정할 수 있다. MAXINRGW의 기본값은 32이므로 기본값으로 사용할 때 최대 연결 가능 Connection 수는 "32 + 30 = 62개"이다.

public class TpcallSample {
        public final String TMAX_HOST_ADDR = "192.168.1.48";
        public final int TMAX_JGW_PORT = 8881;
        public final String BACKUP_HOST_ADDR = "192.168.1.44";public final 
        int BACKUP_JGW_PORT = 8881;
        public final int MAX_THREAD = 20;
        public final int MAX_CONNECTION = 100;
        public String serviceName = "TOUPPER";
        public TpcallSample() {
        }
        public void excute() {
            WebtEndpoint webtEndpoint = new WebtEndpointImpl();
            webtEndpoint.setMainServerInfo(TMAX_HOST_ADDR, TMAX_HOST_PORT);
            webtEndpoint.setFailoverServerInfo(BACKUP_HOST_ADDR, BACKUP_HOST_PORT);
            webtEndpoint.setTimeout(3 * 1000, 4 * 1000);
            try {
                 webtEndpoint.startClientManager("WebT-001", MAX_THREAD, 
                                                 MAX_CONNECTION);
            } 
            catch (IOException e) {
                 e.printStackTrace();
            }
            webtEndpoint.startCheckFailBack(new
            SampleFailBackMonitor(webtEndpoint),5 * 1000, 1 * 1000);
            WebtNService service = new WebtNServiceImpl(webtEndpoint);
            WebtBuffer sndBuffer = new WebtStringBuffer();
            WebtBuffer receiveBuffer = null;
            try {
                 sndBuffer.setString("abc/ABC");
                 receiveBuffer = service.tpcall(sndBuffer, serviceName, 
                                                new WebtAttribute());
                 System.out.println("receive data = " 
                                     + receiveBuffer.getString());
            } 
            catch (WebtException e) {
                   e.printStackTrace();
            } 
            catch (ConnectorException e) {
                   e.printStackTrace();
            } 
            finally {
                 webtEndpoint.stopClientManager();
            }
        }
        public static void main(String[] args) {
                new TpcallSample().excute();
        }
}

tpacall 예제

tpacall의 경우 서비스의 요청에 대한 응답을 받기 위해서 WebtEventHandler를 구현한 callback 인터페이스를 tpacall 호출할 때 설정해 주어야 한다. Tmax로부터 정상 응답을 받는 경우 WebtEventHandler의 handleEvent 메소드가 호출되고, 에러가 발생할 경우 handleError 메소드가 호출된다. WebtEventHandler는 SampleWebtEventHandler 예제를 참고한다.

public class TpacallSample {
        public final String TMAX_HOST_ADDR = "192.168.1.48";
        public final int TMAX_JGW_PORT = 8881;
        public final int MAX_THREAD = 20;
        public final int MAX_CONNECTION = 100;
        public final int BLOCK_TIME = 60;
        public String serviceName = "TOUPPER";
        public TpacallSample() {
        }
        public void excute() {
        WebtEndpoint webtEndpoint = new WebtEndpointImpl();
        webtEndpoint.setMainServerInfo(TMAX_HOST_ADDR,TMAX_HOST_PORT);
        webtEndpoint.setUseOnlyTpacall(true);
        try {
            webtEndpoint.startClientManager("WebT-001", MAX_THREAD, 
                                             MAX_CONNECTION);
        } 
        catch (IOException e) {
           e.printStackTrace();
        }
        WebtNService service = new WebtNServiceImpl(webtEndpoint);
        SampleWebtEventHandler handler = new SampleWebtEventHandler();
        WebtBuffer sndBuffer = new WebtStringBuffer();
        WebtBuffer receiveBuffer = null;
        try {
             sndBuffer.setString("abc/ABC");
             service.tpacall(sndBuffer, serviceName, new WebtAttribute(), handler);
        } 
        catch (WebtException e) {
             e.printStackTrace();
        } 
        catch (ConnectorException e) {
             e.printStackTrace();
        }
        int checker = 0;
        while (true) {
           if (handler.isSuccess()) {
               receiveBuffer = handler.getReceiveBuffer();
               break;
           } 
           else {
              if (handler.isFail()) {
              break;
           } 
           else {
              System.out.println("Data don't receivedyet " + (checker++));
              try {
                   Thread.sleep(1000);
              } 
              catch (InterruptedException e) {
                     e.printStackTrace();
              }
              if (checker >= BLOCK_TIME) {
                  System.out.println("Block Time over("+BLOCK_TIME+")");
                  break;
               }
             }
          }
        }
        webtEndpoint.stopClientManager();
        if (receiveBuffer != null) {
             System.out.println("receive data = " +
             receiveBuffer.getString());
        }
        }
        public static void main(String[] args) {
                new TpacallSample().excute();
        }
}

Xatpacall 예제

WebTAsync에서 트랜잭션은 XA 트랜잭션만을 지원한다. 사용자는 WebTAsync 라이브러리에서 제공하는 XA 리소스 관련 API를 이용하여 XA 처리해야 한다.

tpacall로 서비스를 요청하고 handleEvent에서 메시지 응답을 받은 후 service.getUsingXAResource() 메소드를 이용해 사용 중인 XA 리소스로 end, prepre, commit을 수행한다. XASampleWebtEventHandler는 XASampleWebtEventHandler의 예제를 참고한다.

public class XaTpacallSample {
        public final String TMAX_HOST_ADDR = "192.168.1.48";
        public final int TMAX_JGW_PORT = 8350;
        public final int MAX_THREAD = 20;
        public final int MAX_CONNECTION = 100;
        public final int BLOCK_TIME = 60;
        public String serviceName = "FDLINS";
        public XaTpacall() {
        }
        public void excute() {
                WebtEndpoint webtEndpoint = new WebtEndpointImpl();
                webtEndpoint.setMainServerInfo(TMAX_HOST_ADDR,TMAX_JGW_PORT);
                webtEndpoint.setRecoverHandler(new RecoverWebtHandler());
                try {
                        webtEndpoint.startClientManager("WebT-001",
                        MAX_THREAD, MAX_CONNECTION);
                } 
                catch (IOException e) {
                        e.printStackTrace();
                }
                WebtNService service = new
                WebtNServiceImpl(webtEndpoint);
                XAResource resource = service.getXAResource();
                XASampleWebtEventHandler handler = new 
                XASampleWebtEventHandler(service);
                Xid xid = getUniqueXid();
                try {
                        resource.start(xid, XAResource.TMNOFLAGS);
                } 
                catch (XAException e) {
                        e.printStackTrace();
                }
                WebtBuffer sndBuffer = getEmployeeFieldBuffer(1111);
                WebtBuffer receiveBuffer = null;
                try {
                        service.tpacall(sndBuffer, serviceName, new
                        WebtAttribute(), handler);
                } 
                catch (WebtException e) {
                        e.printStackTrace();
                } 
                catch (ConnectorException e) {
                        e.printStackTrace();
                }
                int checker = 0;
                while (true) {
                        if (handler.isSuccess()) {
                                receiveBuffer = handler.getReceiveBuffer();
                                break;
                        } 
                        else {
                               if (handler.isFail()) {
                                    break;
                                } 
                                else {
                                    System.out.println("Data don'treceived yet " + 
                                    (checker++));
                                    try {
                                        Thread.sleep(1000);
                                    } 
                                    catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    if (checker >= BLOCK_TIME) {
                                       System.out.println("Block Timeover 
                                                    (" + BLOCK_TIME+ ")");
                                       break;
                                    }
                                }
                        }
                }
                webtEndpoint.stopClientManager();
                if (receiveBuffer != null) {
                        System.out.println("receive buffer = " +receiveBuffer);
                }
        }
        private int getRandomIndex() {
                return new Random().nextInt(10);
        }
        private Xid getUniqueXid() {
                byte[] formatId = new byte[4];
                formatId[0] = (byte) getRandomIndex();
                formatId[1] = (byte) getRandomIndex();
                formatId[2] = (byte) getRandomIndex();
                formatId[3] = (byte) getRandomIndex();
                int globalId = getRandomIndex() * 100;
                int branchId = getRandomIndex() * 100;
                return new TmaxXid(formatId, globalId, branchId);
        }
        private WebtBuffer getEmployeeFieldBuffer(int empNo) {
                WebtBuffer sendBuffer = new WebtFieldBuffer();
                sendBuffer.createField("EMPNO").add(empNo);
                sendBuffer.createField("ENAME").add("tmax001");
                sendBuffer.createField("JOB").add("qa");
                sendBuffer.createField("MGR").add(7839);
                sendBuffer.createField("SAL").add(1000);
                sendBuffer.createField("COMM").add(100);
                sendBuffer.createField("DEPTNO").add(20);
                return sendBuffer;
        }
        public static void main(String[] args) {
                new XaTpacallSample().excute();
        }
}

WebtEndpoint는 Tmax와 CLH 또는 Async Java 게이트웨이로 접속 할 수 있는데 XA 서비스를 요청하는 경우 반드시 Async Java 게이트웨이 포트로 접속해야만 한다.

CLH로 접속하여 Non XA 서비스를 요청하는 경우에는 WebtEndpoint로 접속 후 반드시 아래 설정을 해야한다.

webtEndpoint.setUseOnlyTpacall(true);

SampleWebtEventHandler 예제

WebtEventHandler interface를 구현한 클래스로 서비스 요청에 대한 응답 결과를 수신하여 성공하는 경우 handleEvent가 호출되며 실패하는 경우 handleError가 호출된다.

public class SampleWebtEventHandler implements WebtEventHandler {
        private WebtBuffer receiveBuffer;
        private boolean success;
        private boolean fail;
        public SampleWebtEventHandler() {
        }
        public void handleError(WebtException we) {
                fail = true;
                System.out.println("handleError = " + we.toString());
        }
        public void handleEvent(int type, WebtBuffer buffer, int len,int flags) {
                receiveBuffer = buffer;
                success = true;
                System.out.println("handleEvent");
        }
        public WebtBuffer getReceiveBuffer() {
                return receiveBuffer;
        }
        public boolean isSuccess() {
                return success;
        }
        public boolean isFail() {
                return fail;
        }
}

XASampleWebtEventHandler 예제

XA 서비스 처리를 위하여 WebtEventHandler 인터페이스를 구현한 클래스로 서비스 요청에 대한 응답 결과를 수신하여 성공할 때 handleEvent가 호출되며 실패하는 경우 handleError가 호출된다.

public class XASampleWebtEventHandler implements WebtEventHandler {
        private WebtNService service;
        private boolean fail;
        private boolean success;
        private WebtBuffer receiveBuffer;
        public XASampleWebtEventHandler(WebtNService service) {
                this.service = service;
        }
        public void handleError(WebtException we) {
                try {
                        IWebtNXAResource resource 
                         = service.getWebtNUsingXAResource();
                        resource.end(service.getXid(), XAResource.TMFAIL);
                } catch (XAException e) {
                        e.printStackTrace();
                }
                fail = true;
                System.out.println("handleError = " + we.toString());
        }
        public void handleEvent(int type, WebtBuffer buffer, int len,int flags) {
                try {
                        IWebtNXAResource resource 
                        = service.getWebtNUsingXAResource();
                        Xid xid = service.getXid();
                        resource.end(xid, XAResource.TMSUCCESS);
                        resource.prepare(xid);
                        resource.commit(xid, true);
                } catch (XAException e) {
                        e.printStackTrace();
                }
                receiveBuffer = buffer;
                success = true;
                System.out.println("handleEvent");
        }
        public WebtBuffer getReceiveBuffer() {
                return receiveBuffer;
        }
        public boolean isFail() {
                return fail;
        }
        public boolean isSuccess() {
                return success;
        }
}

2.2.3. 주요 기능

Timeout 설정

메시지를 전송할 때 수신을 기다리는 시간과 Tmax에 접속을 시도하는 시간은 WebtEndpoint의 setTimeout(long connectTimeout, long readTimeout)으로 설정한다. 단위는 millisecond이다.

setTimeout 메소드는 전역으로 설정하는 방법이며 매 메시지 전송마다 설정은 WebtNService의 다음의 메소드를 사용한다.

tpacall(WebtBuffer sndBuffer, String serviceName, WebtAttribute attribute, 
        long readtimeout, WebtEventHandler handler)

Timeout이 발생하였을 경우에는 사용자의 handler의 handleError를 호출한다. 자세한 사항은 tpcall 예제를 참고한다.

Fail-Over

WebtAsync 라이브러리는 tpacall시 접속된 연결이 없으면 재연결을 시도한다. WebtEndPoint의 setMainServerInfo로 설정한 메인 서버에 연결할 수 없다면 setFailoverServerInfo에 설정된 백업 서버로 연결을 시도한다. 자세한 사항은 tpcall 예제를 참고한다.

Fail-Back

백업 서버로 연결되어 있는 중 메인 서버가 다시 살아나면 메인 서버로 재연결하도록 WebtEndPoint는 startCheckFailBack을 지원한다. 이 메소드는 현재 백업 서버로 연결되어 있다면 메인서버 살아 있는지 체크해서 사용자에게 알려주는 메소드이다. 사용자는 인자로 들어가는 FailBackMonitor를 구현하여 availableMainServer가 호출되면 메시지를 suspend시키고 모든 메시지가 수신후에 접속을 종료하면 다음부터 오는 메시지는 메인 서버로 보내지게 된다. 메인 서버가 살아났는지 체크하기 위해서 스레드를 하나 생성한다. 자세한 사항은 tpcall 예제를 참고한다.

public class SampleFailBackMonitor implements FailBackMonitor {
        private WebtEndpoint webtEndpoint;
        public SampleFailBackMonitor(WebtEndpoint webtEndpoint) {
                this.webtEndpoint = webtEndpoint;
        }
        public void availableMainServer() {
                webtEndpoint.disconAllConnections();
                System.out.println("Disconnected all connection!!");
        }
}

Transaction Recovery

트랜잭션 처리 중 시스템 장애로 인하여 Tmax에 pending된 트랜잭션이 발생하였다면 다시 접속을 맺을 시에 pending된 트랜잭션을 처리하기 위하여 WebtAsync 라이브러리는 Tmax에서 pending된 트랜잭션 xid list를 얻어와서 사용자 애플리케이션에 해당 트랜잭션의 decision을 문의한다.

public class RecoverSampleWebtHandler implements WebtNRecoverHandler {
        public RecoverSampleWebtHandler() {
        }
        public Xid[] recoverRecieved(Xid[] xids) {
             TmaxXid xid = null;
             for (int i = 0; i < xids.length; i++) {
                xid = (TmaxXid) xids[i];
                xid.setDecision(Webt.TM_XA_COMMIT);
                // xid.setDecision(Webt.TM_XA_RBACK);
              }
              return xids;
        }
}

로그 관련 기능

selector-thread에서 옵션에 따라서 요청전문 (Tmax Header 제외)을 로그레벨에 상관없이 지정한 길이만큼 Hexa로 로그를 남긴다.

webtasync.appmsg.isdump=<true | false>
webtasync.appmsg.dump.length=<Length>
  • webtasync.appmsg.isdump=<true | false>

    기능을 활성화시킨다.

  • webtasync.appmsg.dump.length=<Length>

    요청전문 중 출력할 데이터의 길이를 설정한다.

참고

사용자 애플리케이션은 WebtNRecoverHandler의 recoverRecieved 메소드를 구현하는 경우 decision을 정의해야 한다. 자세한 내용은 Xatpacall 예제 내용을 참고한다.