SAP BUSINESS ONE COMPLIANCE GUIDE FOR DEVELOPERS AND SYSTEM ADMINISTRATORS

SAP BUSINESS ONE COMPLIANCE GUIDE FOR DEVELOPERS AND SYSTEM ADMINISTRATORS

3137373 - DIAPI_Slow Performance When Working With

DI API

Symptom

  You are working with the Data Interface API (DI API) add-on and you are affected by slow performance issues.

Cause

  System behavior/ Functionality description/ Business process

Solution

  When performing transactions using DI API, you may experience the slow performance.

  General checks to optimize performance,

Multi-threading Programming

  Do not use multi-threading programming. DI API does not support multi-threading

Web Service Implementation

  If you are using DI API in Web Service Implementation, then use DI Server/Service Layer. DI

Server/Service Layer better responds to such a requirement, mainly for performance and scalability, by implementing a connection pooling mechanism to manage multiple clients simultaneously.

  If you are hosting on IIS, its is recommended to set 'maximum worker process' to 1.

3063212 - Troubleshooting DIServer Random Crash and

Performance Issues

Symptom

You have developed application based on DIServer and you experience the following in random interval:

o   DI Server Crashes. o DI Server application is not responding to request.

o   DI Server hangs or induces performance issue in the Business One system

Solution

1.  DI Server crashes or does not respond, because of high memory usage  Reason:

B1_DIServer.exe is a 32 bit application. All 32 bit applications have an OS memory limitation of 2 GB(theoretical), but in real world, this limit will be hit much earlier say close to 1.2 GB, depending on the resource available for the OS.

Solution:

       Please refer SAP Note: 3063691. DI Server component is available in 64 bit from SAP Business One 10.0 FP2111

       Scheduled restart can help to clear the memory. Follow the below steps: 1) Open Notepad

2)      Add the following lines in the open text file:

a.       net stop SBODI_Server

b.      net start SBODI_Server

3)      Click the File menu and select Save As. Type a name for the file and save with the .BAT extension.

4)      Open Task Scheduler

5)      Once Task Scheduler opens, in the right, Actions pane window click Create Task.

6)      In the Create Task window, under General tab, type a name for the service. Enable the "Run whether user is logged on or not" and "Run with highest privileges".

7)      On the Triggers tab select New.

Begin the task: On a schedule

Settings: Select the option needed. e.g. Daily

Select the Start: day and time the task will start triggering. If set for Daily, Weekly or Monthly the time configured will be used for the recurring triggers.

8)      On the Actions tab, click New.

Action: Start a program

Program/script: Click the Browse... button and navigate to your saved .bat file.

9)      Leave the rest of the settings default and select OK again to create the task. You will be prompted to enter user credentials with administrative rights if "Run with highest privileges" was selected.

10)  Now click Task Scheduler Library folder in the left column, verify that the schedule has been created and is listed.

    You can also programmatically restart the service like below after a specified period of time, when there is no response for your request

Dim sc As ServiceController = NewServiceController() sc.DisplayName = "SAP Business One DI Server" If sc.Status = ServiceControllerStatus.Running Then     sc.Stop()     sc.Start() End If.

2.  DI Server application hangs or creates long standing database locks. Reason:

Issue is caused by DB Connection recycling. The DB connection between the B1_DIServer.exe and the database is closed after a period of idle time. In this case, session will be alive but the DB connection will be lost.

Solution:

    Change Configuration in DIServer as below: 1) Open the SAP Business One Service Manager 2) Choose DI Server.

3)      Open settings

4)      Under 'Connection string', change the value of 'Minimum Connections' to a higher value let say 20. Keep the default 'Maximum Connections' to value 100. 5) Restart the service.   

3063691 - Installation of the 64-bit Server Tools

Components: System Landscape Directory, License

Service, Job Service, Work Flow, DI Server

Symptom

When you install the server tools with the installation package of SAP Business One running on Microsoft SQL, the components System Landscape Directory (SLD), License Service, Job Service, Workflow, DI Server and Service Manager are 32 bits. When you install the server tools with the installation package of SAP Business One, version for SAP HANA, the components Workflow, DI Server and Service Manager are 32 bits.

Solution

Scenario 1:

You are installing the server tools applications like System Landscape Directory (SLD), License Service, Job Service, Workflow and DI Server from SAP Business One for MSSQL installation package via Setup Wizard.

Scenario 2:

You are installing the server tools applications like Workflow and DI Server from SAP Business One, version for SAP HANA installation package via Setup Wizard.

System behavior prior to SAP Business One 10.0 FP2111 release:

The applications are 32 bits. The installation folder Packages.x64\Server Tools\ exists.

System behavior after SAP Business One 10.0 FP2111 release:

The applications are 64 bits. The installation folder Packages.x64\Server Tools\ does not exist. The server tools components are installed from Packages.x64\ComponentsWizard.

1269591 - Application Freezes During Open Global

Transaction

Symptom

An Add-on is running on the company database. The Add-On modifies marketing documents inside a GLOBAL TRANSACTIONS (StartTransaction() and EndTransaction()).

Other users may be affected such that the SAP Business One application freezes during:

       Accessing Marketing documents

       Accessing any module in the Main Menu

       Login to a company database

(or)

The database is locked by the open Global Transaction process and ending user actions with error code: - 2038.

Cause

Consulting

Solution

The Global Transaction method "StartTransaction" is used when data operations are performed on several business objects.

 

When updating marketing documents related tables will be locked as well. For example:

       Document Numbering (ONNM, NNM1, ...)

       Journal Entry (OJDT, JDT1, ...)

 

These related objects can be relevant for unrelated actions in SAP Business One application. For example:

       Creating other marketing documents,

       Launching other modules or

       Initializing the UI (User Interface) environment on login.

Once the objects are locked by the open global transaction, no access is allowed. This results in a freeze of the application.

Recommendations:

1.       Every StartTransaction should be completed with the EndTransaction method. NN

2.       Use the GLOBAL TRANSACTION only for short duration transactions with less concurrency.

3.       If you are running complex time consuming logic, please schedule such activity on nonproductive hours.

4.       Make sure logic involving GLOBAL TRANSACTION does not wait for user inputs.

5.       Do not use multithreaded programing with GLOBAL TRANSACTION, this will lead to data inconsistency. Be aware DI API (Data Interface API) does not support multithreading.

6.       Employ retry mechanism in case of deadlock error code – 2038.Check note: 1444532.

7.       Do not use UI API (User Interface API) method if you have already started DI API (Data Interface API) method inside GLOBAL TRANSACTION.

1444532 - SDK Deadlock Handling while using Global transaction

Symptom

When you use DIAPI,with starttransaction() and endtransaction() to process mass data operations in a high concurrent environment, database deadlock may occur sometimes. Cause

Consulting

Solution

It is always recommended to keep the logic less time consuming under global transaction.

When a deadlock occurs (error code -2038), the add-on should catch the exception and retry. In most cases, you can resolve the deadlock by retrying the operation or transaction.

 

The following program is an example of deadlock handling:

mainFunc()

{

const long DEADLOCK_ERR_CODE = -2038; long DeadlockTryTime = 5; long i =0; int retCode = 0;

for (i=0; i<DeadlockTryTime; i++)

{ try {

company.StartTransaction(); retCode = DoOperations();  if (retCode == success)

{

company.EndTransaction(SAPbobsCOM.BoWfTransOpt.wf_Commit)

; break;

}

else if (retCode == DEADLOCK_ERR_CODE)

{

//error code returned by DI object operations continue;

} else

{

//other error handling

} }

catch (System.Runtime.InteropServices.COMException ex)

{

//exception thrown from DI service operations

if (ex.ErrorCode == DEADLOCK_ERR_CODE)

{ continue;

} else

{

//other exception handling

}

        }

}

if (i == DealockTryTime)

{

//return error, throw deadlock exception, or other error handling

} }

int DoOperations()

{

//Your logic to perform BO operations.

}

2261279 - DI API:How To Handle Memory Leak In COM

Objects

Symptom

When using Data Interface API (DI API) COM objects, you find memory is not released and API actions are slow.

Cause

System behavior/ Functionality description/ Business process

Solution

For the best performance and memory handling consider below recommendation.

       Use one Company connection per database schema and avoid repeated connections.

       In general, it should be sufficient to initialize the object once and release the object at the end of a loop.

       Declare & instantiate COM objects at the last moment possible.

       ReleaseComObject(obj) or FinalReleaseComObject(obj) for ALL objects, at the soonest moment possible.

       Always ReleaseComObject(obj) or FinalReleaseComObject(obj) in the opposite order of creation.

       NEVER call GC.Collect() except when required for debugging.

       If you are planning to create a program which will be running for several hours continuously, or creating 1000's of documents with multiple child objects, then explicit memory release should be considered.

       If you running a DI API program as a windows service, it is recommended to schedule a restart at least once a day.

Example with respect to DI API, adding Sales Order

 

2493965 - Slower Performance with 64-Bit UIDI

Connection

Symptom

You are using a 64-bit UIDI connection and creating or updating documents using Data Interface (DI) API. The create/update time is slower in a 64-bit than in a 32-bit DI API.

Reproducing the issue Scenario:

1) Create an application with a UIDI connection.

SAPbouiCOM.SboGuiApi SboGuiApi = null; string sConnectionString = null; SboGuiApi = new SAPbouiCOM.SboGuiApi();

sConnectionString=System.Convert.ToString(Environment.Get

CommandLineArgs().GetValue(1));

SboGuiApi.Connect(sConnectionString);

SBO_Application = SboGuiApi.GetApplication(-1);

SBO_Application.MessageBox("Connection to UI API Successfull", 1,"Ok","",""); oCompany = new SAPbobsCOM.Company(); oCompany =

(SAPbobsCOM.Company)SBO_Application.Company.GetDICompany(

);

SBO_Application.MessageBox("Connection to DI API

Successfull", 1,"Ok","","");

2)  Add a user menu and on MenuEvent, execute a DI process to create a document. In the below example, a Delivery Note is created.

SAPbobsCOM.Documents oDelivery = null;

SAPbobsCOM.Document_Lines oDeliveryLines = null; oDelivery =

(SAPbobsCOM.Documents)oCompany.GetBusinessObject(SAPbobsC

OM.BoObjectTypes.oDeliveryNotes); oDeliveryLines =

(SAPbobsCOM.Document_Lines)oDelivery.Lines; oDelivery.CardCode = "C20000"; oDelivery.DocDate = System.DateTime.Now; oDelivery.DocDueDate = System.DateTime.Now; for (int i = 0; i < 50; i++)

{ if (i > 0) oDeliveryLines.Add(); oDeliveryLines.ItemCode = "A00001"; oDeliveryLines.WarehouseCode = "01"; oDeliveryLines.UnitPrice = 100.11; oDeliveryLines.Quantity = 1;

}

int RetVal = oDelivery.Add();

3)      Compile the application with 32-bit DLLs and run the application in a 32-bit SAP Business One Client.

4)      Compile the application with 64-bit DLLs and run the application in a 64-bit SAP Business One Client.

5)      Compare the time taken by the application in step 4 to that in step 5.

Actual behavior:

The 64-bit application is slower than the 32-bit application.

Cause

Limitation

Solution

The slowness is caused by the combase.dll while assigning the properties in a 64-bit DI API.

Workaround:

1)      You can use DI API XML method, instead of assigning properties directly.

SAPbobsCOM.Documents oDelivery = null; oDelivery =

(SAPbobsCOM.Documents)oCompany.GetBusinessObject(SAPbobsC

OM.BoObjectTypes.oDeliveryNotes); oCompany.XmlExportType =

SAPbobsCOM.BoXmlExportTypes.xet_ExportImportMode; oCompany.XMLAsString = false;

oDelivery.Browser.ReadXml(@"C:\Delivery.xml", 0); int RetVal = oDelivery.Add();

2)      You can create a proxy to create documents in a single-thread apartment (STA) thread. The attached zip file 'STAThreadProxy.zip' is a sample.

NOTE : The issue is also reproduced when using a UIDI connection with Single Sign On.

2795858 - COM Interface Performance Downgrade in

Windows 10 Build

Symptom

You are using Microsoft Windows Build version (10.0.14393 Build 14393) or higher and making COM interface calls in your program. You witness a performance downgrade in the process.              

Reproducing the issue Prerequisites:

You are working on Microsoft Windows Build version(10.0.14393 Build 14393), such as Windows 10.0 or Windows 2016 server or higher.

Scenario:

Create a simple COM interface application which loops through 60000 times as below

//Calling program

oTestClass = new testcomRPCLib.testClass(); oTestClass.send1 += new

testcomRPCLib._ItestClassEvents_send1EventHandler(localSe nd1);

Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); oTestClass.Sub(1,3);

TimeSpan ts = stopWatch.Elapsed; string elapsedTimeUI =

String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

//Implementation class

STDMETHODIMP CtestClass::Add(LONG para1, LONG para2)

{

 // TODO: Add your implementation code here

 Fire_send1(para1 + para2);  return S_OK;

}

 

STDMETHODIMP CtestClass::Sub(LONG para1, LONG para2)

{

 // TODO: Add your implementation code here  for (int i = 0; i < 60000; ++i)

 {

  Fire_send1(para1 - para2);

 }

 return S_OK;

}

Note:

Refer to the attached sample program.

Cause

Performance Downgrade in oleaut32.dll

Solution

Microsoft technical support indicates that this performance downgrade is due to changes in O/S design and is likely to be permanent. In Windows 10.x, the call stack in COM Interface "IDispatch_Invoke_Proxy” in oleaut32.dll is much deeper and costs time.

The above behavior will affect the UIAPI calls.

For example: UIAPI application which loops through 100's of rows in a sales order to copy the ItemCode value to the FreeText column:

if (pVal.BeforeAction == true && pVal.FormTypeEx == "139"

&& pVal.EventType ==

SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED && pVal.ItemUID

== "1")

{

    SAPbouiCOM.Form oForm =

SBO_Application.Forms.Item(FormUID);

    SAPbouiCOM.Matrix oMatrix =

(SAPbouiCOM.Matrix)oForm.Items.Item("38").Specific;     SAPbouiCOM.EditText oItemCode, oFreeText;     string Item;

    int RowCount = oMatrix.RowCount;     for (int i = 1; i <= RowCount; i++)

    {

        oItemCode =

(SAPbouiCOM.EditText)oMatrix.Columns.Item("1").Cells.Item

(i).Specific;

        Item = oItemCode.Value;         if (!Item.Equals(""))

        {

              oFreeText =

(SAPbouiCOM.EditText)oMatrix.Columns.Item("163").Cells.It em(i).Specific;

              oFreeText.Value = "Line " + i + ": " +

Item;

        }

    }

}   

Recommendations:

       Design an application which will minimize the UI API operation.

       Use batch operations such as DB Datasource to load a matrix/grid.

       Use necessary event filters to reduce the number of events generated.

2280427 - Slower Performance with 64-Bit than 32-Bit DI

API When Using Recordset DoQuery() for UDT

Symptom

Performance is much slower with 64-bit Data Interface API (DI API) than 32-bit DI API when inserting/selecting data into/from the table (For Inserting: No Object table) in SAP Business One with Insert or Select commands using Recordset DoQuery() method.

Reproducing the issue Scenario:

1.       Write code to make a connection with 32-bit DI API and 64-bit DI API.

2.       Use the Select/Insert command in the code to read/write data from/into a userdefined table (UDT).

3.       Use the Recordset and DoQuery() method.

Example:

Dim selectQuery = String.Format("SELECT * From [@TEST]", tableName) recordset =

CType(DiCompany.GetBusinessObject(SAPbobsCOM.BoObjectType

s.BoRecordset), SAPbobsCOM.Recordset) recordset.DoQuery(selectQuery)

Expected behavior:

The performance is not slower with 64-bit DI API than with 32-bit DI API.

Actual behavior:  

The performance is slower with 64-bit DI API than with 32-bit DI API.

Cause

Future Version Candidate (FVC)

Solution

Correction of system behavior is not feasible in the currently supported versions of SAP Business One. The error has been recorded and is a candidate to be fixed in a future version.

Workaround:

You can use new DI API object RecordsetEx to replace RecordSet, and you can find the detail information in DI API help document.

Example:

Dim selectQuery = String.Format("SELECT * From [@TEST]", tableName) recordsetEx =

CType(DiCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset

Ex), SAPbobsCOM.RecordsetEx) recordsetEx.DoQuery(selectQuery)

Other terms

32 bit, 64 bit, Performance, poor performance