Tuesday, April 2, 2013

Orphaned messages in the BizTalk tracking database


Orphaned messages in the tracking database - where do they come from?

My SQL Agent job Monitor BizTalk Server was failing with the error Orphaned DTA Service Instances in BizTalkDTAdb, that is my tracking database.
Successful execution of this job signals that you have none of the following issues (so you do want it to run J):
·         Messages without any references
·         Messages without reference counts
·         Messages with reference count less than 0
·         Message references without spool rows
·         Message references without instances
·         Instance state without instances
·         Instance subscriptions without corresponding instances
·         Orphaned DTA service instances
·         Orphaned DTA service instance exceptions
·         TDDS is not running on any host instance when global tracking option is enabled.
Looking into this error I’ve realized (via tests) that such orphaned messages in the tracking database are actually created in a number of situations, for instance when:
·         there is no subscribers to a message received in a pipeline using the XMLReceive receive pipeline
·         the receive pipeline fails due to bad data
This post on the BizTalk Administrator Blog discusses possible resolutions to this error:
http://biztalkadmin.com/orphaned-messages-in-the-tracking-database/


First off all, if you wonder if you have any orphaned messages in the BizTalk database i recommend you to use the MessageBox Viewer this will show you the information you need, you can also use the following query:
select count(*) from [BizTalkDTAdb].[dbo].[dta_ServiceInstances] where dtEndTime is NULL and [uidServiceInstanceId] NOT IN (
SELECT [uidInstanceID] FROM[ BizTalkMsgBoxDb].[dbo].[Instances] WITH (NOLOCK)
UNION
SELECT [StreamID]
FROM [BizTalkMsgBoxDb].[dbo].[TrackingData] with (NOLOCK))
As you can see this will look for instances in the tracking database (BizTalkDTADb) where there is no end time. and then make sure the service instance id is not in the message box. It’s vital to use the “WITH (NOLOCK)” when querying towards the production SQL servers in order to make sure you don’t hold any looks.
What have happened? Well basically the message went out without informing the BizTalk tracking database that it is completed.
If you happened to experience a number above 2000 you should clean this. You can do it by using the Terminator toll or by running the following query:
NOTE: This is may violate Microsoft support agreement! Do it at your own risk.
USE [biztalkDTADb]
UPDATE [dbo].[dta_ServiceInstances]
SET [dtEndTime] = GetUTCDate()
WHERE dtEndTime is NULL AND [uidServiceInstanceId]
NOT IN(
SELECT [uidInstanceID]
FROM
BizTalkMsgBoxDb.[dbo].[Instances] WITH (NOLOCK)
UNION SELECT [StreamID]
FROM
BizTalkMsgBoxDb.[dbo].[TrackingData] WITH (NOLOCK))
This query actually puts the time now as end time. It will not remove the orphaned messages until the purge and archive job has passed the desired time for keeping the messages.

BizTalk Server 2010: Database BizTalkDTADb


This article will contain information about the BizTalkDTADb database. Including references to articles that is important for the tracking database. If you have some more information regarding tables, please update them accordingly.

Tables

This section will cover all tables, the one bolded out has information of them. This will be updated as soon as possible.
BizTalkDBVersionThis tables store the information of the current version of your BizTalk environment. Since each BizTalk database has this table, it can also be used for identification of the database at hand, see BizTalkAdminBlogging  
dta_AdapterThis table stores all the adapters installed in your environment, FTP, FILE etc. including all third-party adapters.
dta_ArchiveHistory
Keeps information from the latest backups of the archiving job of from the tracking database.
dta_CallChain
dta_CallChainTemp
dta_Cubes
dta_DebugTraceThis table stores information from orchestration, this data is used for the Orchestration debugger. If you have set 'Shape start and end' tracking on your orchestrations, data will be written for these events in this table.
dta_DebugTraceTempTemporary table for orchestration debugger tracking table.
dta_DecryptionSubject
dta_Group
Contains information of the BizTalk group.
dta_HostStores information of all the hosts in the environment
dta_ItemsThis table stores information of the used tables in the tracking database, including friendly name and type id.
dta_ItemTypesStores information of the type name and type id for the Items table.
dta_MessageBoxStores information of the messageboxes and related info regarding it, or them.
dta_MessageFieldsWill come back to this table
dta_MessageFieldValuesWill come back to this table
dta_MessageFieldValuesTempWill come back to this table
dta_MessageInOutEventsStores information of all in and out events of your BizTalk database
dta_MessageInOutEventsTempTemporary information for in and out events.
dta_MessageStatusThis tables is predefined and includes the state ID for the different message states.
dta_PartyNameContains id and name for parties.
dta_PortNameContains all information of all ports, send and receive ports.
dta_ProcessStateName of the different states.
dta_RulesStores information of all the rules in the Business rules engine
dta_RulesAgendaUpdatesKeeps information of updates in a rule that has tracking turned on.
dta_RulesConditionEvaluation
dta_RuleSetEngineAssociation
dta_RuleSets
dta_RulesFactActivity
dta_RulesFired
dta_SchemaName
dta_ServiceInstanceExceptions
dta_ServiceInstancesStores information of all service instances.
dta_ServiceInstancesTempTemporary table for service instances.
dta_ServicesHolds information of all services that has passed in BizTalk.
dta_ServiceStateDefines the different states with state name of the services, in the above table.
dta_ServiceSymbols
dta_SigningSubject
EdiMessageContent
EdiMessagePartContent
MarkLogThis table holds all the transaction marks set to this database during backup. Each (BizTalk) database which is being backed up by the 'Backup BizTalk Server' job has this table. Note that this table does not clean itself, you need to run the terminator tool to clean it up.
TDDS_FailedTrackingDataTracked messages that failed on transfer from the Message box to the tracking database.,
TDDS_StreamStatusStatus of the message stream from the TDDS
TrackingData
Contains information of tracking data in the tracking database
TrackingDataPartitionsTrackingMessageReferences
TrackingSpoolInfo
Information for the spool table in the tracking database
RunningInstances
Monitors all active instances in the tracking database
btsv_Tracking_FragmentsContains fragments of all messages in the tracking database
Tracking_Parts
Contains information of the parts of a message in the tracking database
Tracking_SpoolThe spool table for the Tracking data

Tables to be aware of

There are a few tables to monitor and make sure are not crossing its secret border. This may differ from company to company. But the databases that gets the most load are:
dta_ServiceInstances
Contains information of all instances, this is turned on by default if you have default tracking on, therefor this table may get very big if jobs aren't running as they should.
dta_MessageInOutEventsThis table contains data of all in and out events of BizTalk, Receive and send ports. This one is also on by default and can only be turned off by turning global tracking off.
dta_DebugTraceThis table contains information for the Orchestration Debugger, in case you have this turned on in all application, or have orchestrations that are doing a lot of work this table may get very big as well.

SQL Queries

Be aware that all queries towards the BizTalk databases should be with a NO LOCK

Find Orphaned messages in the tracking database

SELECT count(*) from [BizTalkDTAdb].[dbo].[dta_ServiceInstances]
WHERE dtEndTime is NULL and [uidServiceInstanceId]
NOT IN (
SELECT [uidInstanceID] FROM [BizTalkMsgBoxDb].[dbo].[Instances] WITH (NOLOCK)
UNION
SELECT [StreamID]
FROM [BizTalkMsgBoxDb].[dbo].[TrackingData] WITH(NOLOCK))

Query Transactions

NOTE: Change red text into date (DD-MM-YYYY HH:MM:SS) 
SELECT datepart(hh, [dtInsertionTimeStamp]) as timeMsg, datepart(dd, [dtInsertionTimeStamp]) as dateMsg, count(Convert(char(10), [dtInsertionTimeStamp], 108)) as ant
FROM [BizTalkDTADb].[dbo].[dta_MessageInOutEvents] WITH (NOLOCK)
WHERE [dtInsertionTimeStamp]
BETWEEN convert(datetime, '11-03-2011 23:00:00', 120) AND convert(datetime, '11-04-2011 22:59:59', 120)
GROUP BY datepart(hh, [dtInsertionTimeStamp]), datepart(dd, [dtInsertionTimeStamp]) ORDER BY [dateMsg ]ASC, [timeMsg]

Query Instances

NOTE: Change red text into date (DD-MM-YYYY HH:MM:SS)

SELECT datepart(hh, [dtInsertionTimeStamp]) as timeMsg, datepart(dd, [dtInsertionTimeStamp]) as dateMsg, count(Convert(char(10), [dtInsertionTimeStamp], 108)) as ant
FROM [BizTalkDTADb].[dbo].[dta_ServiceInstances] WITH (NOLOCK)
WHERE [dtInsertionTimeStamp]
BETWEEN convert(datetime ,'11-03-2011 23:00:00' 120) AND convert(datetime, '11-04-2011 22:59:59*, 120)
GROUP BY datepart(hh, [dtInsertionTimeStamp]), datepart(dd, [dtInsertionTimeStamp] ) ORDER BY [dateMsg] ASC, [timeMsg]

Query transaction by host name

NOTE: Change red text into date (DD-MM-YYYY HH:MM:SS)

SELECT dbo.dta_Host.strHostName, count(dbo.dta_ServiceInstances.dtInsertionTimeStamp) as ant
FROM dbo.dta_Host WITH (NOLOCK)
INNER JOIN dbo.dta_ServiceInstances WITH (NOLOCK) ON dbo.dta_Host.nHostId= dbo.dta_ServiceInstances.nHostId
WHERE dbo.dta_ServiceInstances.[dtInsertionTimeStamp]
BETWEEN convert(datetime, '10-30-2011 23:00:00', 120) AND convert(datetime, '10-31-2011 22:59:59', 120)
GROUP BY strHostName ORDER BY ant DESC

Get message count for all applications from In Out Events

use biztalkdtadb
SELECT COUNT(dbo.dta_MessageInOutEvents.dtTimestamp) AS ant, BizTalkMgmtDb.dbo.bts_application.nvcName
FROM dbo.dta_MessageInOutEvents WITH (NOLOCK)
INNER JOIN BizTalkMgmtDb.dbo.bts_receiveport WITH (NOLOCK)
INNER JOIN dbo.dta_PortName WITH (NOLOCK) ON BizTalkMgmtDb.dbo.bts_receiveport.nvcName = dbo.dta_PortName.strPortName ON
dbo.dta_MessageInOutEvents.nPortId = dbo.dta_PortName.nPortId
INNER JOIN BizTalkMgmtDb.dbo.bts_application WITH (NOLOCK) ON BizTalkMgmtDb.dbo.bts_receiveport.nApplicationID = BizTalkMgmtDb.dbo.bts_application.nID
GROUP BY BizTalkMgmtDb.dbo.bts_application.nvcName order by ant desc

Note: This will only look for receive ports (which is more than enough)

Useful BizTalk SQL queries


Marklog:
Marklog is a table in the BizTalk databases, it store a string every time BizTalk backups the database, this is a known bug in BizTalk 2006 – 2009. And it will most probably never be fixed, make sure the marklog table isn’t too big, it might give you some performance issues.
SELECT [MarkName] FROM [BizTalkDTADb].[dbo].[MarkLog] WITH (NOLOCK)
See count of all messages and port name for a specified date. (as long as you have tracking on all receive and send ports.
SELECT CONVERT(char(10), [BizTalkDTADb].[dbo].[dta_MessageInOutEvents].[dtInsertionTimeStamp], 101) AS InDate, COUNT([BizTalkDTADb].[dbo].[dta_MessageInOutEvents].[nPortId]) AS numb, dta_PortName.strPortName AS name FROM [BizTalkDTADb].[dbo].[dta_MessageInOutEvents] WITH (NOLOCK) INNER JOIN [BizTalkDTADb].[dbo].[dta_PortName] WITH (NOLOCK) ON [BizTalkDTADb].[dbo].[dta_MessageInOutEvents].[nPortId] = [BizTalkDTADb].[dbo].[dta_PortName].[nPortId] WHERE [BizTalkDTADb].[dbo].[dta_MessageInOutEvents].[dtInsertionTimeStamp] BETWEEN CONVERT(datetime, 05-10-2011 00:00:00′, 120) AND CONVERT(datetime,05-17-2011 23:59:59′, 120) GROUP BY CONVERT(char(10), [dta_MessageInOutEvents].[dtInsertionTimeStamp], 101), [dta_PortName].[strPortName] ORDER BY InDate, numb DESC
The last is just a simple count of all messages registered in the MessageInOutEvents.
SELECT Convert(char(10), [dtInsertionTimeStamp], 101) as date, count(Convert(char(10), [dtInsertionTimeStamp], 101)) as ant FROM [BizTalkDTADb].[dbo].[dta_MessageInOutEvents] WITH (NOLOCK) WHERE [dtInsertionTimeStamp] BETWEEN convert(datetime, ‘05-10-2011 00:00:00′, 120) AND convert(datetime, ‘05-17-2011 23:59:59′, 120) GROUP BY Convert(char(10), [dtInsertionTimeStamp], 101) ORDER BY [date]
Feel free to use these queries as you wish. (remember to change the date in the query).
The following query will tell you when during a day you have the most queries passing through BizTalk.

SELECT datepart(HH, [dtInsertionTimeStamp]) as date,
count(Convert(char(10), [dtInsertionTimeStamp], 108)) as ant FROM [BizTalkDTADb].[dbo].[dta_MessageInOutEvents] WITH (NOLOCK) WHERE [dtInsertionTimeStamp] BETWEEN convert(datetime, ‘01-01-2011 00:00:00′, 120) AND convert(datetime, ‘07-08-2011 23:59:59′, 120) GROUP BY datepart(hh, [dtInsertionTimeStamp])ORDER BY [date]
all you need to do is change the date after the WHERE clause.
Make sure the dates are within the time you have tracking stored, and the query execution time will vary depending on how many massages you have during a day and for how long you want to gather the information.

Monday, January 21, 2013

How to send SOAP headers in BizTalk


How to send SOAP headers in BizTalk

Here are the steps to set SOAP headers in a web service request using BizTalk Server 2004 (BTS).

1. Make sure your web reference in your BTS project is up to date.

2. Open the Reference.xsd for the wsdl of the web service. Look for the name of the root node for their Soap Header. Here is the example I'm using...

<soap:Header>
<AuthenticationHeader xmlns="http://www.acme.com/WebService/">
<strUserName>string</UserName>
<strPassword>string</Password>
</AuthenticationHeader>
</soap:Header>



3. Copy the name. Close the file.

4. Create a new item for the BTS project. Select "Property Schema" NOT the regular schema.
- In the properties for <schema>,
Change the target NameSpace to http://schemas.microsoft.com/BizTalk/2003/SOAPHeader
- In the properties for the root node,
Rename the root node the same as the one is step 2 ("AuthenticationHeader")
Change the Property Schema Base drop-down to "MessageContextPropertyBase"

5. Save the file as "SoapHeader.xsd" and Close the file. (Update: It doesn't matter what the name is as long as the TYPE NAME property of the xsd file is not the same as the root node name. Otherwise, you'll run into a compilation error)

6. Go to your orchestration. There should be a Construct Message shape that creates the web service request. There should be a shape inside of it - either a Transform or a Message Assignment.
If it is a Transform, add a Message Assignment below that in the SAME Construct Message shape.
If it is a Message Assignment, do nothing as we will reuse the existing one.

7. Edit the Message Assignment from step 6 and add the following as one line....

SampleWS_Request_Msg(MyBizTalkProject.AuthenticationHeader) =
"<ns0:AuthenticationHeader xmlns:ns0=\"http://www.acme.com/WebService/\">
<ns0:UserName>MyName</ns0:UserName>
<ns0:Password>NotSoSecretPassword</ns0:Password>
</ns0:AuthenticationHeader>";

Where
- "SampleWS_Request_Msg" is the message variable name in the Orchestration for the external web service.
- "MyBizTalkProject" is your project name
- "AuthenticationHeader" is the name of the property schema

Note: Once you type the message name and the first parentheses "SampleWS_Request_Msg(" an intellisense drop-down list appears and the property schema you are looking for should appear.


Note 2: There is another option to use an existing SOAP header from another message, but I had to use this approach as the incoming message was a Flat File.
Note 3: If you are using SOAP over standard HTTP, please keep in mind that the above message contents (including SOAP Header) can be clearly viewed by others monitoring internet traffic. I don't advocate this as a security measure

Sunday, January 20, 2013

Oracle Forms 10g Tuning tips


Oracle Forms 10g Tuning tips

Although there are quite some new screenbased application techniques, a lot of companies use the traditional Oracle Forms & Reports.
Even with the transition to an entire new application server, WebLogic, Oracle has  ported their traditional applications like Forms to the 11g stack.
In this article I will guide you to some performance improving techniques I gained from my year to year experience working with Middleware products

The  Oracle HTTP Server

Oracle HTTP listener receives the request.
It forwards the request to MOD_OC4J that handles all servlet requests. MOD_OC4J decides if it is intended for Forms since the path “/forms/frmservlet”
matches one of the OC4J mount directives in the forms90.conf or forms.conffile (the one for the Forms Servlet).
MOD_OC4J maps the request to the Oracle Forms application (whose context root is /forms90 or /forms) in the OC4J servlet engine.
MOD_OC4J passes the request to the Forms Servlet (using the f90servlet or frmservlet servlet mapping specified in the web.xml file).
The Forms Servlet (running in OC4J) processes the request as follows: It opens the servlet configuration file (formsweb.cfg by default)
and starts to donwload the file to the client machine.
If the paramter envfile is not set, the default configuration file (<ORACLE_HOME>/forms90/server/formsweb.cfg) or (<ORACLE_HOME>/forms/server/formsweb.cfg)is used.
HTTP Tuning
These parameters in the httpd.conf are relevant for tuning:
- KeepAlive
- MaxClient
- MinSpareServers
- MaxSpareServers
- KeepAliveTimeout
- MaxRequestsPerChild
- ThreadLimit
- ThreadsPerChild
- Global-thread-pool
There are some possibilities for tuning which are listed in more detail in the
following:
1. Limit the number of processes (HTTPD on Unix; THREAD on NT) to avoid spawning too many HTTPD processes (which is memory consuming). Don’t set the LD_ASSUME_KERNEL option!
2. Set the following directive in the Oracle HTTP Listener configuration file httpd.conf:
KeepAlive Off
If you must use KeepAlive On (for example, for another application), make sure that KeepAliveTimeout is set to a low number (for example, 15 seconds,
which is the default). It keeps the current TCP/IP connection open for awhile after the HTTP transaction ends, allowing that same connection to be used for several subsequent HTTP transactions. So it reduces latency, and speeds up both the client and server connections. But for forms every new connection is a new transaction.
3. Set the maxClient directive to a high value.
The best is to let the HTTP Listener control to create more HTTPD daemons.
Therefore set the maxClient directive to a high value in the configuration file (httpd.conf).
However, you need to consider the memory available on the system when setting this parameter. You can let the HTTP Listener determine when to create more HTTPD daemons. Therefore, set the MaxClients directive to a high value in the configuration file (httpd.conf). However, you need to consider the memory available on the system when setting this parameter.MaxClients=256 means that the listener can create up to 256 HTTPD processes to handle concurrent requests.
4. MinSpareServers / MaxSpareServers
If your HTTP requests come in bursts, and you want to reduce the time to start the necessary HTTPD processes,
you can set MinSpareServers and MaxSpareServers within httpd.conf) to have an appropriate number of processes ready.
However, the default values of 5 and 10 respectively are sufficient for most sites.
5. The MaxRequestsPerChild directive sets the limit on the number of requests
that an individual child server process will handle. After MaxRequestsPerChild requests, the child process will die.
If MaxRequestsPerChild is 0, then the process will never expire. This directive sets the maximum configured value for ThreadsPerChild for the
lifetime of the Apache process. Any attempts to change this directive during a restart will be ignored, but ThreadsPerChild can be modified during a
restart up to the value of this directive.
6. ThreadsPerChild
This directive sets the number of threads created by each child process. The child creates these threads at startup and never creates more.

OC4J tuning Section


You can specify the use of a thread pool for an OC4J process through the global-thread-pool element in the server.xml file.
If you do not specify the use of a thread pool, OC4J will create the number of threads that is necessary required to service your application
workload in an unbounded fashion.
You can configure OC4J to create a single thread pool containing all threads. The other way is that two thread pools are created containing different types
of threads, through the <global-thread-pool> element in the server.xml file.
If you do not specify this element, then an unbounded number of new threads are created as needed for the OC4J process.
Example
=======
<strong>&lt;application-server ...&gt;</strong>
<strong>&lt;global-thread-pool min="10" max="100" queue="200" keepAlive="700000"</strong>
<strong>debug="true" /&gt;</strong>
<strong>...</strong>
<strong>&lt;/application-server&gt;</strong>
Recommendations:
The queue attributes should be at least twice the size of the maximum number of threads.The minimum and maximum number of worker threads should be a multiple of the number of CPUs installed on your machine and fairly small. The more threads you have, the more burden you put on the operating system and the garbage collector. The minimum that you should set is 10.
When running benchmarks or in a production environment, once you figure out the right number of threads, set the minimum to the maximum number, and the
keepAlive attribute to negative one (-1).
Take care when you modify these parameters. It helps in many cases when increasing them. But if the values are too high estimated then the system
starts dramatically to swap and takes most of the time to handle the swapping process. And degrade the system uses memory and CPU time!
To create a single pool, configure the min, max, queue, and keepAlive attributes. To create two pools, configure the min, max, queue, and keepAlive attributes for the first pool and the cx-min, cx-max, cx-queue, and cx-keepAlive attributes for the second pool.
In order to activate two thread pools, you must configure all the attributes for the first thread pool, which includes min, max, queue, and keepAlive. If any of these attributes is not configured, you cannot configure the second pool.
&lt;global-thread-pool min="10" max="100" queue="200"
keepAlive="700000" cx-min="10" cx-max="100" cx-queue="200"
cx-keepAlive="700000" debug="true"/&gt;

OC4J Java options

- Xms(sizem) -Xmx(sizem)
- Xss
- client
- server
- session-timeout
-Xms(sizem) -Xmx(sizem)
If you know that your application will consistently require a larger amount of heap, you can improve performance by setting the minimum heap size equal to
the maximum heap size, by setting the JVM -Xms size = -Xmx size.
Some other usefull settings:
-Xt               turn on instruction tracing
-Xtm              turn on method tracing
-Xbootclasspath[/a|/p]:<path>
set, append to, or prepend to boot class path
-Xdebug           enable remote debugging
-Xnoclassgc       disable class garbage collection
-Xss<size>        set maximum native stack size for any thread
-Xoss<size>       set maximum Java stack size for any thread
-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xrs              reduce the use of OS signals
-Xrunhprof[:help]|[:<option>=<value>, ...]
Perform heap or cpu profiling –>
-Xmaxjitcodesize<size>; set the maximum size (in bytes) for the JIT code area
-Xsqnopause       do not pause for user interaction on sigquit
-Xoptimize        Experimental: Use optimizing JIT compiler (SPARC only)
Possible Errors:
Exception java.lang.OutOfMemoryError: requested <size> bytes
If you see this symptom, consider increasing the available swap space by allocating more of your disk for virtual memory and/or by
limiting the number of applications you run simultaneously.You may also be able to avoid this problem by setting the command-line
flags -Xmx and -Xms to the same value. This prevents the VM from trying to expand the heap. Note that simply increasing the value of -Xmx will not help when no swap space is available.
-client and  -server
Assuming that you are running a lot of bytecodes. Make sure that you are usingthe correct mode of the virtual machine.
For applications that need small footprint and fast startup, use -client.
For applications where overall performance is the most important issue, use -server.
Don’t forget that -server or -client must be the FIRST argument to java (default is -client).
Do not use the -server option when running OC4J on Oracle Application Server for Windows systems.

-Xss

It depends on the particular J2EE application to change the setting of the command line option -Xss for the JVM running OC4J and with that – maybe – to improve performance.
The default C code stack size is 512kb(-Xss512k).
A value of 64kb is the smallest amount of C code stack space allowed per thread. Oracle recommends that you try the following value to improve the performance
of your J2EE applications:
Example
-Xss128k

session-timeout

Set session-timeout parameter to the same or higher value as the Forms90_Timeout or Forms_Timeout parameter. You can set the session-timeout parameter in the
web.xml file that configures the Forms Servlet. The default timeout in Oracle AS is 20 minutes.
To set the session time-out to 15 minutes do the following:
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
web.xml file is present in the following directory:
OracleAS –> j2EE –> OC4J_BI_Forms –> applications –> forms90app or formsapp –>forms90web or formsweb –> Web-inf
MaxBlockTime

MaxBlockTime is the time in milli seconds to wait when reading data from the Runform process.
e.g. a long query, lots of complex processing
(default = 1000 milli sec)
/j2EE/OC4J_BI_Forms/application/forms90app/forms90web/WEB-INF/web.xml
or
/j2EE/OC4J_BI_Forms/application/formsapp/formsweb/WEB-INF/web.xml
Example
<servlet>
<servlet-name>l90servlet</servlet-name>
<servlet-class>oracle.forms.servlet.ListenerServlet</servlet-class>
<init-param>
<param-name>maxBlockTime</param-name>
<param-value>1800000</param-value>
</init-param>
</servlet>
or
<servlet>
<servlet-name>lservlet</servlet-name>
<servlet-class>oracle.forms.servlet.ListenerServlet</servlet-class>
<init-param>
<param-name>maxBlockTime</param-name>
<param-value>1800000</param-value>
</init-param>
</servlet>
Explained
For long requests (like querying a big table), the ListenerServlet waits for a default time of 1 second for the Forms runtime process to complete the request If the request is not completed then the Listener Servlet sends a busy response to the client asking the client to retry.
The client sends a retry zero content length request to check if the query is complete.This default time of 1 second can be configured using Listener Servlet
parameter called maxBlockTime

OC4J Load Balancing for Forms


The easiest way to do this is to increase the number of oc4j processes.
Choose Oracle Enterprise Manager (OEM) Website
–> Select the Midtier instance
–> OC4J_BI_FORMS
–> Server properties.
Choose Multiple VM Configuration and there increase the “Number of process”.
Check for Island ID (default = 1).
Save the changes.
This can also be seen in the opmn.xml file under the opmn directory of the Midtier.
But take care if you have defined 2 OC4J instances and you have set the Parameter -Xms=512M.  The instance then allocates 1,1 GB Memory( 2* 515MB).
If you set this parameter (Xmx and Xms) you have to be sure that you have enough physical memory. Otherwise you will get an error message when you try to start the instance.
If run into OC4j timeouts you can continue to change following options that can in the mod_oc4j.conf file:
Oc4jConnTimeout 30
Oc4jCacheSize 0
Oc4jUseKeepalive on

If you want to loadbalance, and there are two hosts in an Oracle Application Server cluster: Host_A and Host_B. Each has Oracle HTTP Server and OC4J processes running on them, then add the following to the mod_oc4j.conf:
Oc4jSelectMethod random:local
Oc4jRoutingWeight Host_A 3
Oc4jRoutingWeight Host_B 2

Oc4jRoutingWeight directives are ignored. mod_oc4j on Host_A randomly routes all requests to OC4J processes on Host_A, mod_oc4j on Host_B randomly routes all requests to OC4J processes on Host_B. mod_oc4j on all the machines route requests equally to OC4J processes on Host_A, Host_B, in a round robin manner.

Forms Server Side Tuning

- FORMS90_TIMEOUT / FORMS_TIMEOUT
- heartbeat
- networkRetries
Forms Runtime Pooling enables the startup of a configurable number of application runtime engines prior to their usage. Runtime Pooling provides
quick connections at server peak times, which shortens the server-side application startup time. Runtime pooling is useful for situations where server configurations have a small window in which many users connect to a Forms application. All prestarted runtime engines run in the same environment serving the same application.
Example formsweb.cfg
[appn_b]
form=login_appn_b.fmx
prestartRuntimes=true
prestartInit=5
prestartMin=4
prestartIncrement=3
prestartTimeout=5
FORMSxx_TIMEOUT
This parameter specifies the amount of time (in minutes) before the Forms Server process is terminated when there is no client communication with the Forms Server. The internal default value is 15, and valid values are integers between 3 – 1440 minutes.
Often it happens that the client does not provide any action and Forms starts to terminate the communication between the client and the Forms runtime engine process
This raises errors like FRM-92050, FRM-92100, FRM-92101
Heartbeat
This parameter sets the frequency at which a client sends a packet to the server to indicate that it is
still running (default = 2 min).
Set this parameter value greater than the value specified for the FORMSnn_TIMEOUT variable.
For example set it to 7 minutes as follows after the serverArgs parameter:
For Internet Explorer:
<OBJECT
<PARAM VALUE=”7″>
For mozilla:
<EMBED
….
heartBeat=”7″
If a user is idle, (that is, if they do not use their Form for five minutes) FORMSxx_TIMEOUT kicks in. The higher value given for the
heartbeat setting means that the Forms runtime process thinks that the corresponding client applet session is no longer alive. Therefore the
connection is lost and the Form runtime process for that client is automatically terminated.
networkRetries
This one is specified in the formsweb.cfg.The parameter specifies the number of times the Forms
client should try reconnecting to the middle tier before finally timing out.
networkRETRIES is ONLY applicable when deploying Forms over the web via the Forms Listener Servlet architecture, and NOT the standard Forms Server

Forms specific

This section describes forms specific items
REDUCE NETWORK TRAFFIC
This goal was mentioned before. There a number of tips that affect the efficiency of your forms and that you should work into your initial design. Reducing network traffic is the name of the game for tuning web-deployed forms. Most of the tuning effort required is between the application server and client, as this is the most complex connection and the one that is most unfamiliar to Forms developers. It is useful to review some guidelines for reducing database server network traffic.
OPTIMIZE THE CLASS FILE LOADING
The initial load time of the Java applet can be a bottleneck  with users because it seems longer than the form startup in client/server environments. Part of this time is spent in loading the Java class files on the client side. You can optimize this
task using the following tips. The following list refers to Java Archive (JAR) files that are collections of the Java classes used to Designing, Developing, and Deploying Applications
render objects. You can create and open and manage these files using an archive utility such as WinZip. Most classes are named descriptively, so you can check whether a particular function is in a particular JAR file.
Load a smaller JAR file
JAR files are cached if you use JInitiator. This helps reduce the initial download time to a
minimum. Use the ARCHIVE parameter in your starting HTML file to load one or more JAR files. For example:
PARAM NAME=“ARCHIVE” VALUE=“fweb.jar,icons.jar”. The FWEB.JAR file contains all but the LOV classes and is the one to use if you want to load all common classes when starting up.
Tune the JAVA client Cache
The default Java memory cache on the client is xxMB. Compare that number with memory as the application is running (using a system monitor such as the Windows NT Task Manager), and ensure that you have enough cache space available in memory. Increasing physical memory will help if you are running out of memory and swapping to disk. Freeing memory by closing other applications will also help.
Locate the JAR file centrally
JAR files are housed on different application servers in a load-balancing arrangement,
the same JAR files could be downloaded from different servers because the classes are cached relative to the server.
Locate the JAR files centrally if you have a load-balancing configuration.
Use the Deferred-Load Feature   A deferred-load feature allows you to embed references to other JAR files within a JAR file. The referenced files will not load immediately, but will wait until the class in that file is required. This deferred
loading means that the form can display faster initially, although other classes that are required will be loaded as needed.
Store the .GIF icon files in the JAR file.
This saves download time. .GIF files are used for icons on buttons in webdeployed forms instead of .ICO  files. Some icons are actually supplied by the Runtime engine and do not require .GIF files at all. There is no known list of these icons, but you can experiment with the icons that are used by the default Forms
toolbar (exit, save, etc.). The images will display even if you delete those icons from the icon directory.
Store beans in a JAR   If you are using Java code (JavaBeans or Pluggable Java Components), store them in the JAR file as well to speed up the download
REDUCE BANDWIDTH USAGE
The key factor that differentiates web-deployed forms from client/server forms is their use of the network. Anything you can do to reduce network traffic (that uses available bandwidth, or capacity) will speed up the way the forms load or run. The following points address this principle.
•  Reduce the number of boilerplate text objects, and use the prompt property instead. Boilerplate text is another object that needs to be rendered.
•  Reduce the number of boilerplate graphics. Lines and rectangles are optimized, but other types are not.
•  Change navigation   If your form contains many windows, allow the user to navigate to those other windows by clicking an OK or Done button instead of by pressing TAB to navigate through items. If the user does not need to change anything in those items, it is a waste of time to have to navigate to them. In addition, more triggers will fire as you navigate through items (such as POST-TEXT-ITEM and WHEN-NEW-ITEM-INSTANCE). If the user can skip to the next window with a button, the network traffic required by the item triggers will be eliminated.
•  Use a simple startup form with just a few items on it. An example would be a logon screen with only a few items and graphics. This loads faster.  Designing, Developing, and Deploying Applications
•  Hide objects not initially required. Set the canvas property Raise on Entry to “Yes.” Set other objects’ Visible property to “No.” Also set Raise on Entry to “Yes.” Neither of these are the default values. When the cursor navigates to the item, Forms will automatically display the canvas. You can also issue a SHOW_VIEW call to set the Visible property to “Yes” programmatically. Tab canvases load all objects for the entire set of tabs at the same time. Set the Visible properties of all items to “No” to counteract this. Set them back to “Yes” when you navigate to a particular tab.

Wednesday, December 26, 2012

bizTalk Oracle Adapter Limitations


Adapter Limitations

This topic has not yet been rated Rate this topic
The following are known limitations of the Microsoft BizTalk Adapter for Oracle Database.
  • Array binding is not supported because it is a performance issue. According to Oracle documentation, if you include a large amount of data in a single Biztalk message to the adapter, you gain performance because there are fewer network round trips between the Oracle database and the adapter; however, the Oracle ODBC driver tries to minimize these network calls when array binding is not used.
  • BFile is supported as an IN parameter only.
  • BFile and BLOB cannot be used with the Table methods, Insert, Update, or Query.
  • Large object (LOB) types are supported as IN parameters only. When they appear as INOUT, RETURN and OUT, the procedure is not displayed in the browser, and therefore is not callable. LOBs are supported in tables in the Insert, Update, or Query methods.

    There are two types of LOBs: a character LOB (CLOB) and a binary LOB (BLOB). The remove method on the table is available on CLOB tables because BizTalk Adapter for Oracle Database does not have to know the types of the columns in the table to remove all data.
  • When a table contains columns of types that are not supported by the adapter for that database system, the table only shows the Remove method.
  • Some PL/SQL stored procedures have a parameter of a user-defined data type for an Oracle Table. Packages that contain PL/SQL using a cursor or a ref cursor, as in some native APIs, do not generate the schema.
  • Records and cursors are not supported as return types as either input or output of stored procedures, as the ODBC driver does not define the metadata for these.
  • User-defined types (objects) are not supported for stored procedure in/inout/out/return types.
  • Empty strings and strings with only white space characters are treated as NULL string by BizTalk Adapter for Oracle Database. Oracle also treats a character with a length of zero as null.
Literal Number Support
Oracle treats literal numbers differently. Internally the database requires numbers to be formatted with the semi-colon instead of the period. Refer to Oracle documentation for more information about how Oracle treats literal numbers: www.cs.umb.edu/cs634/ora9idocs/server.920/a96540/sql_elements3a.htm#3411.