Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

BAPI_TRANSACTION_COMMIT problem

Former Member
0 Kudos

In a .net program, according to the messages returned from SAP, I am getting a Purchase Order created using BAPI_PO_CREATE1.   In fact every time I execute, I get a new next higher number PO.   That seems to  be working fine.

Also, Immediately after the BAPI returns to my .net program I am then executing BAPI_TRANSACTION_COMMIT.  

However when I look in SAP, the PO does not exist.

The RETURN structure from the BAPI_TRANSACTION_COMMIT is initial.  So there are no errors there.

I've tried this with the same results for both WAIT = X and WAIT defaulting in BAPI_TRANSACTION_COMMIT.

Is there a special place in the process where this BAPI_TRANSACTION_COMMIT should be called?   I "assumed" immediately after the CREATE PO BAPI is called would have been the correct time and  place.

1 ACCEPTED SOLUTION

jitendra_it
Active Contributor
0 Kudos

Hi Wardell,

If I am getting your question correctly , its a two step process. first u call bapi PO to create PO then

u call BAPI_TRANSACTION_COMMIT to commit work.

After the first step when the call returns back to .net program , the data of buffer in sap got refreshed and when u call commit in second step , there is no data in buffer to write to database.

if u want to achieve this functionality then u have to write a customer RFC , in which u call PO  bapi then u call BAPI_TRANSACTION_COMMIT. Now call this RFC in ur .net program.

Many Thanks,

Jitendra

9 REPLIES 9

former_member200345
Contributor
0 Kudos

Hi,

What are the messages that you receive in the return table of the bapi 'BAPI_PO_CREATE1'?

Check the import parameter 'TESTRUN', this parameter must be blank inorder to create the PO.

Regards,

Vijaymadhur.

jitendra_it
Active Contributor
0 Kudos

Hi Wardell,

If I am getting your question correctly , its a two step process. first u call bapi PO to create PO then

u call BAPI_TRANSACTION_COMMIT to commit work.

After the first step when the call returns back to .net program , the data of buffer in sap got refreshed and when u call commit in second step , there is no data in buffer to write to database.

if u want to achieve this functionality then u have to write a customer RFC , in which u call PO  bapi then u call BAPI_TRANSACTION_COMMIT. Now call this RFC in ur .net program.

Many Thanks,

Jitendra

0 Kudos

Hi Jitendra,

Not necessarily; as long as the connection used in the create BAPI is still open, you must still be able to commit it.

Hi Wardell,

Can you please share the return messages for BAPI_PO_CREATE1?

Regards,

Karl

0 Kudos

Hi Karl,

the return to .NET causes an interrupt that does a database commit. Because BAPIs make extensive use of PERFORM ON COMMIT, they are not executed. This only happend with explitic COMMIT WORK (as issued in BAPI_TRANSACTON_COMMIT).

You may try Jitendra's suggestion.

Regards

Clemens

0 Kudos

There were no return messages from the COMMIT BAPI, which I assume meant the commit was suuccessful.

former_member206632
Participant
0 Kudos

Hi Wardell,

From my experience using external calls to BAPI's that need commit, here's how I managed to solve that problem:

  1. I created a Z copy of the original BAPI;
  2. The Z_BAPI calls the original BAPI and BAPI_TRANSACTON_COMMIT at the end;

And that's it! Of course I'm not very proud with this solution, but it works. Another solution would be using an implicit enhancement point of the original BAPI (at the end) and test the session parameters (user, user type, etc) in order to decide wheter or not call BAPI_TRANSACTON_COMMIT - it works too!

Regards,

João

0 Kudos
All,
Thanks to everyone for their replies.  However I was able to find the solution.   The solution was to  wrap the BAPI_PO_CREATE1 function object into a Transaction object, then commit the transaaction after calling the BAPI to create the PO.   I ended up NOT calling Commit BAPI (at least not explicitly).
C# code snippet follows:
...........
RfcTransaction transaction = new RfcTransaction();  //Create a transaction object
transaction.AddFunction(function);  //Add BAPI_PO_CREATE to the transaction object
...........               
RfcSessionManager.BeginContext(destination);   //Begin the transaction
function.Invoke(destination);       //Call BAPI_PO_CREATE
transaction.Commit(destination);     //Transaction object
RfcSessionManager.EndContext(destination); //End the transaction
........

david_burg
Participant
0 Kudos

Creating a custom RFC with built-in commit is not the right approach for this problem: you're doing server-side ABAP changes while the issue is with the C# client needing to call the stateful BAPI RFC in the same context as the commit call so that the right LUW is understood by SAP to complete. Often client side programmers don't have dev access to SAP server to change or add to RFCs. The problem is that by default the connection is stateless, the BAPI RFC is never matched with the commit and vice versa. The commit returns a dummy success that just indicates that SAP committed the default empty transaction. Instead the two calls needs to be bound together. The approach of using an RfcTransaction object for that is correct. Another approach may be to pin the context on the RfcDestination with BeginContext, then call the BAPI RFC, then explicitly call the BAPI COMMIT, then optionally call EndContext (will work without but nicer to JCo / Nco to allow clean up of the contexts it keeps track of).

markus.tolksdorf did I get this right?

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert

Using an RfcTransaction implies that it is executed as asynchronous request and the application will not get response parameters. Hence, if a synchronous processing is desired, using RfcSessionManager.BeginContext/JCoContext.begin to start a stateful sequence in which both the BAPI and BAPI_TRANSACTION_COMMIT are invoked, is the only valid approach. Hence, you got this right, but I am not considering the RfcSessionManager.EndContext/JCoContext.end optionally, because if not using them you would delay the release of backend resources to the point in time the session is finalized on the connector side and this all open connection associated with this session are released. Good coding style will release resources as early as possible.

Best regards,
Markus