In the SAP Interface Programming NCo3.0 series (06): Session Management in this article, the relevant knowledge points for session management have been described in detail, please refer to. Now use JCo3.0 to achieve.
1. Jcocontext
If multiple functions in SAP need to be run in a session, you need JCoContext
to provide a guarantee. If you are in the same thread, the general pattern is this:
JCoContext.begin(sapDestination);fm1.execute(sapDestination);fm2.execute(sapDestination);JCoContext.end(destination);
After the function execute between Begin () and end (), SAP does not release the connection to ensure the same session.
The second case: if a different function is not in the same thread, it needs to be implemented by the developer SessionReferenceProvider
Interface, providing the session ID in the class. Logic is the same with nco3.0. JCO3.0 provides a sample code, but it's too complicated, I got a simple, easy to understand.
2. SAP functions
The function we are going to use is from the standard system functionINCREMENT_COUNTER
, GET_COUNTER
copied. In the SAP systemINCREMENT_COUNTER
, GET_COUNTER
in the same function group, share a variable count (counter), each runINCREMENT_COUNTER
, Count adds one, and the GET_COUNTER
function
You can get this count. Because these two functions cannot be called remotely, we copy the two functions Zincrement_counter and Zget_counter.
3. Executing functions in the same thread
First, we define two functions in a class RfcFunctions
:
Package Jco3.demo6;Import com.sap.conn.jco.JCoDestination;Import com.sap.conn.jco.JCoException;Import com.sap.conn.jco.JCoFunction;PublicClassrfcfunctions{PublicStaticIntrungetcounter (jcodestination dest) throws jcoexception {jcofunction COUNTERFM = Dest.getrepository (). GetFunction ( "Zget_counter"); Counterfm.execute (dest); int counter = (int) counterfm.getexportparameterlist (). GetValue ( "get_value"); return counter;} public static void runincrement (jcodestination dest) throws jcoexception {jcofunction increment = Dest.getrepository (). GetFunction (" Zincrement_counter "); Increment.execute (dest); }}
Then write the test class to test:
Package Jco3.demo6;Import Com.sap.conn.jco.JCoContext;Import com.sap.conn.jco.JCoDestination;Import Com.sap.conn.jco.JCoDestinationManager;Import com.sap.conn.jco.JCoException;PublicClasstestsessionsamethread{PublicStaticvoidMain(string[] args)Throws Jcoexception, Interruptedexception {Get Jcodestination Object instance jcodestination Destination = Jcodestinationmanager.getdestination ("ECC");Make sure the functions is executed in the same session jcocontext.begin (destination);//before increment System.out.println ( "before execution of Zincrement_counter: "); System.out.println ( "Counter:" + rfcfunctions.rungetcounter (destination)); //Run incrementcounter five times for ( int i = 0; i < 5; i++) { Rfcfunctions.runincrement (destination); System.out.println ( "ADD:" + (i + 1));} //after increment System.out.println ( "after execution of Zincrement_counter: "); System.out.println ( "Counter:" + rfcfunctions.rungetcounter (destination)); //release the connection jcocontext.end (destination);}
The code is intuitive, and it's not much to say. Before the function executes, the value of counter is 0, and after the function is run 5 times, the value of counter is 5. If we comment out JCoContext.begin(destination);
and JCoContext.end(destination);
, we can compare different effects.
4. Executing functions in different threads
If different functions are executed in different threads, the developer is required to provide the session ID. I'm going to put two functions in a different thread:
- Called in the main thread of the JVM
ZGET_COUNTER
to see the results of the counter.
- Running in another thread
ZINCREMENT_COUNTER
, two threads are kept under the same session ID by Jcocontext.
4.1 Implementing the Jcosessionreference interface
JCoSessionRefence
The primary function of the implementation class is to provide the session ID:
Package jco3.session;Import Java.util.concurrent.atomic.AtomicInteger;Import com.sap.conn.jco.ext.JCoSessionReference;PublicClassJcosessionrefenceimplImplementsjcosessionreference{Private Atomicinteger Atomint =new Atomicinteger (0); private String id = "session" +string.valueof ( Atomint.addandget (1)); public void contextfinished () {} public void contextstarted () {} @Override public String getid () { /** * We need to override GetID () method */return ID;}}
4.2 Implementing the Sessionreferenceprovider interface
In the SessionReferenceProvider
implementation class of the interface, rewrite the getCurrentSessionReference()
method to get the JCoSessionRefence
session ID as defined above. Other methods remain motionless.
Package jco3.session;Import com.sap.conn.jco.ext.JCoSessionReference;Import com.sap.conn.jco.ext.SessionException;Import Com.sap.conn.jco.ext.SessionReferenceProvider;PublicClassSessionreferencproviderimplImplementssessionreferenceprovider{@OverridePublic jcosessionreferenceGetcurrentsessionreference(String Scopetype) {/** * We need to override Getcurrentsessionreference () method */Jcosessionrefenceimpl Sessionref =New Jcosessionrefenceimpl ();return sessionref; }@OverridePublicBooleanIssessionalive(String SessionID) {ReturnFalse }Publicvoidjcoserversessioncontinued (String SessionID) throws sessionexception {} public void Jcoserversessionfinished (String SessionID) {} public void jcoserversessionpassivated (String SessionID) throws sessionexception {} public jcosessionreference Jcoserversessionstarted () throws SessionException {return null;}}
4.3 Registering the Sessionreferenceprovider interface
Register SessionReferenceProvider
the implementation class of the interface, so that JCoDestination
there is a state management function.
Package jco3.session;Import com.sap.conn.jco.JCoDestination;Import Com.sap.conn.jco.JCoDestinationManager;Import com.sap.conn.jco.JCoException;Import com.sap.conn.jco.ext.Environment;import com.sap.conn.jco.ext.SessionReferenceProvider; public class destinationprovider{public Span class= "Hljs-keyword" >static jcodestination getdestination () throws jcoexception {//Create an instance of Sessionreferenceprovider //and register in environment Sessionreferenceprovider Provider = new Sessionreferencproviderimpl (); Environment.registersessionreferenceprovider (provider); Jcodestination Destination = jcodestinationmanager.getdestination ( "ECC"); return destination; }}
4.4 Executing zincrement_counter in a separate thread
Define Workingthread, which inherits from the thread class and executes the function Zincrement_counter 5 times in this thread.
Package Jco3.demo6;Import com.sap.conn.jco.JCoDestination;Import com.sap.conn.jco.JCoException;PublicClassWorkingthreadExtendsthread{PrivateBoolean donesignal;Private jcodestination destination;ConstructorPublicWorkingthread(Jcodestination destination,Boolean donesignal) {This.destination = destination;This.donesignal = donesignal; }PublicBooleanHasdone() {return donesignal;} @Override public void run () {/** * Run method of Runincrement () for five times */for (int i = 0; I < 5; i++) {try {rfcfunctions.runincrement (this.destination); System.out.println ( "Run" + (I+1) + " Times. ");} catch (jcoexception e) {e.printstacktrace ();}} this.donesignal = true;}
The donesignal is used to identify whether the thread ends. The thread itself ends and the run () method finishes running.
4.5 Testing multithreaded function calls
Well, finally to test the function call in multi-threading:
Package Jco3.demo6;Import Com.sap.conn.jco.JCoContext;Import com.sap.conn.jco.JCoDestination;Import com.sap.conn.jco.JCoException;Import Jco3.session.DestinationProvider;PublicClasstestsapsessionmultithread{PublicStaticvoidMain(string[] args)Throws Jcoexception, Interruptedexception {/** * Run Zincrement_counter & zget_counter functions in * different threads in a stateful the. * * The SAP would keep a session ID which is created in * Jcosessionreferenceimpl class * and used in Sessionreferenceprov Iderimpl class. * * Before using, Sessionreferenceproviderimpl class should be * registered using Environment.registersessionreferencepro Vider () method. */Get Jcodestination Object instance jcodestination Destination = Destinationprovider.getdestination ();Make sure the functions is executed in the same session jcocontext.begin (destination);Before Increment System.out.println ("Before execution of Zincrement_counter:"); System.out.println ( "Counter:" + rfcfunctions.rungetcounter (destination)); //start a new Thread in which function Zincrement_counter //would Be executed for five times workingthread workingthread = new workingthread (destination, false); Workingthread.start (); //wait and Switch thread thread.sleep (1000); //after increment if (workingthread.hasdone () = = true) {System.out.println ( "after execution of Zincrement_counter:"); System.out.println ( "Counter:" + rfcfunctions.rungetcounter (destination));} //release the connection jcocontext.end (destination);}
The main differences from the code in the previous thread are:
Define an instance of the Workingthread class, and then start the thread:
WorkingThread workingThread = new WorkingThread(destination, false);workingThread.start();
Then Thread.sleep()
, by switching the thread to Workingthread, the execution is completed and the result is displayed back to the main thread.
Wen/stonewm (author of Jane's book)
Original link: http://www.jianshu.com/p/2ce28196483c
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".
SAP Interface Programming JCo3.0 series (04): Session Management