cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with EndTransaction

Former Member
0 Kudos

Hello,

I am seeing two issues with transactional upload using DIAPI-

Issue 1 -

I am running 2007 DIAPI and get an exception on EndTransaction method call. Please refer to the sample code below.

Issue 2 -

I am trying to create BP's using DIAPI. I have started the transaction but any record that succeeds after a failure gets added. If all records succeed then nothing is uploaded but if say one record fails then any success after gets uploaded (committed).

No upload should happen if StartTransaction is called.

Please find the sample code below.

Has any one seen these problems? Am I missing anything?

Sample Code in C# -

string[] CardCodes = new string[] { "Moon", "Test103", "1002" };

conn.StartTransaction();

foreach (string cardCode in CardCodes) {

SAPbobsCOM.BusinessPartners bp = (SAPbobsCOM.BusinessPartners)conn.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oBusinessPartners);

bp.CardCode = cardCode;

bp.CardType = SAPbobsCOM.BoCardTypes.cCustomer;

int errCode;

string errMsg;

int returnval = bp.Add();

if (0 != returnval) {

conn.GetLastError(out errCode, out errMsg);

Console.WriteLine(errMsg);

}

}

conn.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_RollBack);

Thanks and Regards,

Sheetal

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

Owen, breaking from the for loop does not show me the status on the remaining records.

So I changed my code to check if InTransaction in the for loop. If not, start transaction. This ensures that every record upload is happenning in transaction so that I rollback at the end.

These changes are doing what i was looking for.

Thanks Owen for the hint about the InTransaction check.

string[] CardCodes = new string[] { "Moon", "Test105", "1002" };
            conn.StartTransaction();
            foreach (string cardCode in CardCodes) {
                SAPbobsCOM.BusinessPartners bp = (SAPbobsCOM.BusinessPartners)conn.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oBusinessPartners);
                bp.CardCode = cardCode;
                bp.CardType = SAPbobsCOM.BoCardTypes.cCustomer;
                int errCode;
                string errMsg;
                int returnval = bp.Add();
                if (0 != returnval) {
                    conn.GetLastError(out errCode, out errMsg);
                    Console.WriteLine(errMsg);
                } else {
                    Console.WriteLine("Success");
                }
                
                if (false == conn.InTransaction) {
                    conn.StartTransaction();
                }       
}
            if (conn.InTransaction) {
                conn.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_RollBack);
            }

Regards,

Sheetal

Former Member
0 Kudos

Thanks for the sample code Owen.

I tested it to find the same behavior. After a error the success entry is committed.

In this example I already have a BP with card code "Moon" in my DB. When I run this function it display the error "Entry already exists" as expected for the first card code. The next card code is "Test103" which is valid and it gets added to the DB.

Basically I am trying to reproduce the "TestRun" functionality.

It is not working.

When we start the transaction the InTransaction flag is set to true

int returnval = sboBP.Add();

As soon as the Add returns error the InTransaction flag is set to false.

Now when my second record succeeds we are not in transaction and it gets committed.

How do I reproduce the TestRun behavior?

Now I understand why the EndTransaction was throwing an exception because the InTransaction is already false when I was calling it.

Regards,

Sheetal

former_member201110
Active Contributor
0 Kudos

Hi Sheetal,

I see what you mean. I think you just need to add a break to the foreach loop so that the loop is exited as soon as the first error is encountered:


...
...
     if (0 != returnval)
     {
            _sboCompany.GetLastError(out errCode, out errMsg);
            Console.WriteLine(errMsg);
            break;
     } 

catch(Exception ex)
{
     if (_sboCompany.InTransaction) _sboCompany.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_RollBack);
     Console.WriteLine(ex.Message);
     break;
}

Kind Regards,

Owen

former_member201110
Active Contributor
0 Kudos

Hi Sheetal,

I notice that you've set the transaction to automatically rollback in your example. Is that for test purposes?

As the DI API will automatically rollback a transaction if it encounters an error while updating or adding an object, you just need to check if the company object is still in a transaction at the end of your loop. If the transaction is still open then that means that no error was encountered so you can commit it. I also always put a try/catch clause around and rollback if an exception is encountered.

For example:


string[] sCardCodes = new string[] {"Moon", "Test103", "1002"};
_sboCompany.StartTransaction();
foreach (string sCardCode in sCardCodes)
{
	try
        {
		SAPbobsCOM.BusinessPartners sboBP = (SAPbobsCOM.BusinessPartners)_sboCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oBusinessPartners);
                sboBP.CardCode = sCardCode;
                sboBP.CardType = SAPbobsCOM.BoCardTypes.cCustomer;
                int errCode;
                string errMsg;
                int returnval = sboBP.Add();
                if (0 != returnval)
                {
                	_sboCompany.GetLastError(out errCode, out errMsg);
                        Console.WriteLine(errMsg);
                } 
         }
         catch(Exception ex)
         {
         	if (_sboCompany.InTransaction) _sboCompany.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_RollBack);
                Console.WriteLine(ex.Message);
         }
}
if (_sboCompany.InTransaction) _sboCompany.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_Commit);

The above code should only add the BPs if all of them can be created. If any of them fail then all are rolled back.

Kind Regards,

Owen