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