Part of a series devoted to RDMLX-enabling your LANSA environments.
If you have triggers that test the value of trigger return code before you default the value of trigger return code, those triggers will crash when the I/O comes from an RDMLX function.
You Really Use Triggers?
Today, general wisdom suggests putting your business logic into a callable module so that it can be accessed from a 5250 app, a web app, and a Windows/VL app without modification. Those who created the architecture for our system back in the day believed the correct place for most business logic was in triggers. Because of that decision, triggers are now business critical in our organization.
The Switch That Does Nothing Does Something
Before considering the move to an RDMLX-enabled environment, we performed due diligence to see how well our system works. Most things work so far. However, this decision to RDMLX-enable our environments, that some people have told us “is a no-brainer because it doesn’t change anything,” is not quite so straight-forward in our situation. There ARE things that break.
But You’ve Gotta
LANSA mandates that every trigger default the trigger return code. Every time we’ve asked about this, the answer has been consistent: the examples and templates from LANSA clearly show the correct way to code the trigger return code in templates.
Andersen Software Factory
Our architecture dates back to when the Andersen Software Factory from Andersen Consulting ruled the roost. Raise your hand if you remember the Andersen Software Factory! That PC-based code generator sat on top of LANSA. Yeah, good times. Fortunately, the Software Factory was destined to sleep with the fishes once the Y2K boundary was crossed. In preparation for that glorious event, I was asked to replace it with LANSA templates. The transition went smoothly and a few of the team helped to fully deprecated those PCs… by drilling holes into the hard drives. I wish I had pictures.
That history is important because the Software Factory had a specific way of coding everything. A proper structure is a good thing and the Software Factory had some good stuff. Take conversation control, for example. There were a few places, though, where the structure was broken. Like not defaulting the value of trigger return code in triggers.
RDMLX Blows (Up)
When we began testing our ERP system in an RDMLX environment, we converted some of our RDML functions into RDMLX. We didn’t get one transaction completed because our triggers crashed. It took a couple of hours to figure out the root cause.
The IOM and the OAM are distinct objects that do not communicate with each other and that behave differently. On the iSeries, an IOM is an RPG program which is executed any time an RDML function performs I/O over a file. On the iSeries, an OAM is a C program which is executed any time an RDMLX function performs I/O over a file. (For you LANSA hackers looking for holes in the logic, I am intentionally ignoring *DBOPTIMISE in this example.)
Now let’s test. We create a trigger function that does not default trigger return code but that does test the value of trigger return code. The trigger is called for every insert, update, and delete. We have an RDML function that maintains the file by updating one particular record that already exists. We have an RDMLX function that contains code identical to the RDML function. Identical.
- When you maintain the file from the RDML function, the file’s IOM is used. The IOM defaults the trigger return code to ‘OK’ and passes it to the trigger. When the trigger tests the value of the trigger return code, the test succeeds since the value is ‘OK’.
- When you maintain the file from the RDMLX function, the file’s OAM is used. The OAM defaults the trigger return code to hex X’00′ and passes it to the trigger. When the trigger tests the value of the trigger return code, the function aborts because hex X’00′ is not an alphanumeric value and #TRIG_RETC is an alphanumeric field.
We’ve run this test dozens of times and it appears that although the IOM and the OAM both default the value of trigger return code, the default value in each is different. In the case of the OAM, it appears to be, in our opinion, an invalid value for the field.
To recap, our ERP system seemed to work fine in an RDMLX environment until we introduced RDMLX functions. As soon as they performed I/O, triggers were executed which immediately aborted. Because we have everything under commitment control, this caused the entire transaction to roll back. WAMs would have had the same result.
It appears that our only option is to default trigger return code to OK in every trigger function and to update the templates to do that for all new triggers. Unfortunately for us, this task is not only huge, it is risky. We are in the process of automating this process of updating trigger functions in order to reduce that risk.