Home » CodeProject
Category Archives: CodeProject
In English, we use sentences that are made up of words which are typically separated by spaces (” “) and tabs. We use commas, and semi-colons to create pauses and we keep reading until we see a period. If the sentence is too long to fit on a line (typically 72 – 80 characters on a page). Often times, we feel the need to break in the middle of a word, to keep the right margin neat. For this we use hyphen (“-“).
Programming languages and scripts are not very different. After all, they are made by us, humans. Each language has a set of punctuations like English. As for wrapping a statement onto next line, each language may have it’s own character and conventions. In any case, you cannot break in the middle of a word.
Generally, Microsoft programs and script use hyphen (“-“) to indicate the statement is continuing on the next line. Unix world typically use a backslash (“\”).
DOS/Windows Batch File
See this wiki post for more on this and other punctuation in programs.
EA Server 5.5 comes with a manager application called Jaguar Manager (also called Sybase Central). This is really a Java product, but in this version it’s wrapped in a program called scjview.exe. This is available in %SYBASE%\Shared\Sybase Central 4.3\win32.
I found out this is using an old JRE 1.4. (I use process explorer in Sysinternals. It’s a great tool!). I wanted to switch the EA Server to Java 1.5 , which is the latest version of Java supported in EAS 5.5. With the EA Server itself, this is easy. Just pass -jdk15 to the serverstart batch file.
With Jaguar Manager, this is not as straightforward. There is a batch file called, jagmgr.bat, but this only calls scjview.exe mentioned above. The Java runtime is probably picked up using a DLL named jsyblib142.dll, in %SYBASE%\Shared\win32.
After googling for a bit, I found a solution to this problem. Apparently, scjview.exe has a command line argument -batch.
When you run it like that, the program generates a batch file called sybasecentral.bat in the same directory as scjview.
Now, this batch file runs Java with a bunch of Jar files. You can change the path of the Java command to change the Java version it’s run in. Such a simple solution, completely hidden! And with this available, why did they have to create an EXE like that?? Beats me!
Of course, once you convert to batch file, you can tweak the java parameters such as memory etc to run better.
I recently posted about object life cycle in Sybase EAServer (Jaguar). EAServer provides object pools (cache) where objects are cached when a client lets go of it. Since, the object creation and destroy are so costly, having such an object pool helps with performance immensely.
Last Year, there was a memory leak in one of our EAServers. After debugging the issue, I narrowed it down to couple of methods. Whenever the methods were called, the memory usage seemed to increase. This kept happening until the server ran out of memory and crashed. During our peak season, our web users ended up calling this method more frequently, thus crashing the server sooner.
The real problem was that each time the user called these methods, a new instance of an object (nvo_rtn_processor) was created inside the function and was never let go.
When we looked at the code, the nvo_rtn_processor was being destroyed as expected, but still it was not released for some reason. After analyzing the issue, found that the DESTROY actually caused the issue. Changed to call of_deactivate and it worked out.
A little PB Background
When a new instance of a EA Server component is needed in PB it’s done by calling CreateInstance method in TransactionServer object. This creates an instance on the EA Server side and passes back a reference to it in PB.
For e.g., to create an instance of nvo_rtn_processor, we issued,
Where lnv_rtn_processor is the local reference in PB.
When we are done with the object thus created, we need to let go of it, so it can be returned to pool or garbage collected (see my post on object life cycle). To do this, we could either DESTROY the object or deactivate it.
Typically DESTROY is used for objects that were created using CREATE statement. For objects that were created with CreateInstance, better approach is to use SetComplete on the TransactionServer. (Unless object’s Automatic Deactivation flag is set, then PB will take care of this).
EAServer is distributed environment where distributed components participate in distributed transactions. The components don’t commit/rollback themselves. They merely indicate that they can be committed or rolledback using SetComplete or SetAbort methods. When the Jaguar Transaction Processor sees that, it commits or aborts the component’s changes. This helps Transaction processor to commit or rollback all objects participating in a single distributed transaction.
Solving the mystery
The original developer used DESTROY to get rid of nvo_rtn_processor. This should have worked. Our deactivate and destructor events for this object1 were almost identical. So the issue was not in whether it was destroyed or deactivated. The problem was actually that the component was never “Deactivated”. The key is that we are actually calling a function called of_deactivate which in turn calls SetComplete on the transaction Server. SetComplete actually did the trick – this released the component and thus returned to pool as expected.
// SetComplete to allow instance pooling/destruction
li_result = lts.SetComplete()
The key lesson is that DESTROY only destroys the handle (local variable) to the component, but not the component itself. When nvo_rtn_processor was destroyed, the PB reference and the container reference probably got destroyed, but the actual component was never let go by the TransactionServer object, as we never told it to, thus the memory leak. (If the automatic Demarcation/DeActivation was set for the component, we might not have seen this issue.)
For any component that is created through TransactionServer, we need to call SetComplete (or SetAbort in case of a failure) to complete transaction and deactivate the component. For a lot of components in our application, this is done automatically, by enabling the component’s Automatic Demarcation/DeActivation.
1. The deactivate event for an object will be called when it is deactivated – after SetComplete is called in this case. Destructor event will be called when the object is being destroyed.
2. nvo_rtn_processor itself is not declared transactional, but above discussion is still true irrespective of the transaction type of the component. Automatic Demarcation can be set for components that are not transactional as well. If this is not done, then we must use SetComplete/SetAbort to release the object explicitly.
Fig 1 EA Server Component settings for nvo_rtn_processor.
This post talks about the life cycle of a component, deployed in EA Server, at run time. The component is instantiated on the server by a CreateInstance call from a client (PB) code. The picture below must be self explanatory.
To debug/trace the life cycle, EAServer provides some log/trace flags. By turning on these, we could see the events of a EA Server component life cycle.
Memory allocation is an expensive task in any system. Whether it’s a C program doing malloc or a Java program creating objects on the fly, the system has to constantly go to memory handler and request for more memory. Releasing used memory was also a problem, it took resources, and not releasing properly caused memory leaks. Java came up with Garbage collection (gc), but even this uses a lot of resources, if not setup properly.
In a heavily used system, this means the system will be spending considerable amount of time in object creation and destruction (this will be done by Garbage collection). To alleviate this problem, some type of pooling (or caching) method is often used. Simply put, this is where memory released is held in a pool and reused when the next person asks for it. This way we reduce the number of times objects are created or released.
EA Server offers Object Pooling for components deployed to EA server. When this option is turned on for a component, the object instances are pooled before returning to memory.
EA Server/PB settings that effect Pooling
Our Software uses object pooling option available in EA Server. This option is external to the PB language and is part of EA Server administration. The settings are available in component Properties -> Instances tab in Jaguar Manager.
Below setting enables Pooling for a component in EA Server, if checked.
Fig 1: This defines if pooling needs to be used for a particular object.
Below settings for the component in EA Server define how and when Pooling of the object can take place. As mentioned in the note, an object instance is kept in the pool only if it doesn’t exceed maximum setting. In this case, the pool will have at least 3 instances at any time. By adjusting these settings we can optimize the memory handling for the object. Too low setting for the minimum will cause more frequent garbage collection and too high will keep too many instances in the pool, thus wasting memory.
On the other hand, “Maximum Pooled Instances” setting effects how many can be kept in the pool. In a scenario where this object is constantly requested, increasing maximum setting will help. Again, this also means too many will be sitting in the pool during idle times.
PB settings for Pooling
The below PB settings only decide if the releasing of object reference from PB side is automatic or manual. These settings are set at the component level in EAServer Component Generator (Project Painter).
The actual pooling is effected by the settings on the EA Server side, as mentioned above.
Fig 3: This shows the settings on the PB side.
EA Server object instance life cycle
Below image is a capture of a visio diagram (attached) that attempts to show how pooling plays a role when objects are created from Powerbuilder code. As mentioned, Auto demarcation affects how the object references are released (automatic or manual) on the PB side.
When pooling is enabled for the object on the EA Server side (see Fig1), once the references are released the object instance is typically qualified for garbage collection.
If pooling is enabled, the object instance is then returned to Object Pool in EA Server, if the other conditions are met (see Fig 2).
Fig 3: Object Life Cycle during a typical method call
If you are coming to Oracle from another database, you are in for some surprises. One of them is the key word BEGIN. They don’t mean the same in Oracle. Read on.
A TRANSACTION block
In SQL Standards they list Transaction control statements such as START TRANSACTION, END TRANSACTION and SAVE TRANSACTION. Different database vendors implement this as they see fit. For e.g., Informix always had a “BEGIN [WORK]” statement to mark the beginning of a transaction block. The block will end when an explicit COMMIT or ROLLBACK is issued or SQL ends abnormally (in which case it’s rolled back). See here.
So in non-ORACLE database (Informix for e.g) you may have,
BEGIN [WORK] --(1) INSERT.... UPDATE... DELETE... .. COMMIT [WORK]; -- **commit marks the end of the current transaction**
In Oracle there is no BEGIN [WORK] equivalent. It’s just “understood” when the first executable statement makes some changes to the database. This includes DML and DDL statements. So, the above statement block in Oracle will be written as,
-- **implicit Transaction block begins?** --(1) INSERT.... UPDATE... DELETE... .. COMMIT [WORK]; -- **commit marks the end of the current transaction**
So, there you have it. In Oracle, an implicit transaction block is started when the first INSERT statement is executed and it is not started with a BEGIN or START.
BEGIN…END in Oracle
But then, you have surely seen a BEGIN (and END) in Oracle? Yes, you are correct about that statement being there, only it’s a statement in PL/SQL not plain SQL. PL/SQL is a separate procedural programming language in Oracle, just like C or Java, only PL/SQL is specialized to handle SQL more efficiently1.
This BEGIN statement in PL/SQL can be easily confused with BEGIN [WORK] in other databases, if you are new to Oracle. A BEGIN..END block in PL/SQL is merely a syntactical collection of statements (SQL, non-SQL). They don’t relate to transactions. However, since a bunch of SQL statements inside the BEGIN..END block mark a single PL/SQL statement, a COMMIT (or ROLLBACK) after a PL/SQL block could commit (or rollback) entire list of SQL statements within the PL/SQL block, thus implying BEGIN had to do with a new transaction. Not so! Suppose you ran the below block in SQL*Plus. Let’s say you updated a table. Try SELECTing the record you just updated, in another session. You won’t see the change yet, because we have not committed the below statement. That also shows END doesn’t have anything to do with Transaction.
-- **PLSQL BLock 1** BEGIN -- **SQL statements** END; / And as another example, if you had couple of PL/SQL block (BEGIN...END) before a COMMIT is issued, statements in both those blocks are committed. -- **PLSQL BLock 1** BEGIN --**SQL statements** END; / -- **PLSQL BLock 2** BEGIN --**SQL Statements** END; / COMMIT;
Here COMMIT applies to all the statements PLSQL blocks 1 and 2, showing us that PL/SQL block does not correspond to a transaction block.
 I think, differentiating between SQL and PL/SQL is the biggest challenge a newcomer to Oracle faces. PL/SQL is a procedural language with control structures like if, loops etc. You can build stored programs like Oracle Procedures, Triggers, Functions and Packages only in PL/SQL. It’s tightly coupled with Oracle SQL Engine causing some confusion. I will post more on this later.
I admit. I have old PCs hanging around. I know it’s hoarding, but you may need something from it, some day! Like the one with Windows 2000. I recently decided to get rid of it. But, I wanted to move the programs and data from the hard disk to a new one, so I can use it in a machine. The drive was an old Maxtor 80GB hard drive. It had old Windows 2000, so I didn’t bother with the OS files. I just wanted to copy the documents and other files (may be even some programs I wrote) to my new computer. This drive used the old PATA technology.
I normally get a external hard drive enclosure, so I could attach it as an external USB drive and copy files from it. This time I got a little adventurous (cheap?) and went for a SATA/PATA hard drive adapter, something like this. Essentially, it’s open ended cable with SATA or PATA pins available to plugin the hard drive. There is no safeguard compared to a hard disk enclosure.
I got my PATA drive hooked up to my computer via USB using this adapter. Everything was going well. Except, it is not hot-swappable – meaning you can’t plug and unplug while the thing was on. I did that and the next thing I know, the inevitable happened! I smelled smoke and surely, the drive was fried.
I thought it was gone. I researched a bit about data recovery and all. Sounded so expensive. Then I landed on this site called PCB Solutions. According to this site, apparently when you smell smoke on a hard drive, chances are it’s only the PCB circuit that sits on tops that’s fried, not the disk or the platter. So, in theory, if you can replace this PCB board, you can salvage any drive. Really? I’ve worked with SCSI hard drives for a while, when I worked for a SCSI software company in the past. Never knew those things came off like that.
It’s the L-shaped circuit board (in green with chips) that comes off the top of the drive.
The site offers really good service. First the identifying/matching service. Lets you enter a few codes/numbers and matches the PCB needed for your drive. Once you pay and order it, it arrived within a week or so. The package comes with a kit – a small screw driver included. So, anyone can remove the old plate and replace it with the new one. Voila!! That worked!
It was that simple. I’ve done some hardware stuff, but I can’t claim to be an expert in that area. I was able to do this easily. Great service, great support. I highly recommend this for anyone at a loss of their precious hard drive. This service can save you 100’s if not thousands. You just need some patience and some caution. (Like don’t touch the circuit part, not to zap it by accident etc).