This is part 4 of a post series about EBR.
In part 1 we created the baseline model and code – a table (PEOPLE) and two packages (PEOPLE_DL and APP_MGR).
In part 2 we saw that even a simple change – a package body compilation – can be dangerous in a busy system.
In part 3 we learned about editions and how they can be used for solving the problems described in part 2, so changes can be applied in both online and safe way. I discussed enabling, creating and using editions; session edition; and editioned objects.
In this part we’ll see more challenges that online upgrades bring – this time when changing a package spec.
Visit the index page for all the parts of the series
This time we need to change the PEOPLE_DL package spec. There are no table changes, and of course, as we speak about EBR, the upgrade from the previous version to the new one should be online.
An online upgrade means that the application users should be able to continue working uninterruptedly. The code objects that they use should remain valid and available at any time.
In addition to the challenges raised from the first use case – changing PEOPLE_DL package body – the current use case introduces another challenge: invalidation. Changing the PEOPLE_DL package spec will cause its dependent objects become invalid.
Even if the change does not cause any compilation errors in the dependent objects, they become invalid.
Actually, even if we just recompile an object, without making any changes in it, its dependent objects still become invalid.
Now, it’s true that in these cases revalidation will occur automatically as soon as the invalid object is used, but in an online upgrade scenario this is usually unacceptable.
Moreover, many times we need to change multiple interrelated objects. For example, changing the API of some procedure in one package, and consequently changing it in the package body and changing the calls to that procedure from another package. In this case we cannot avoid having broken objects – invalid and with compilation errors – during the upgrade, and this is obviously cannot be really considered an online upgrade.
The Transaction Concept
It would be nice if we could compile all these objects in a single transaction, as one atomic operation, so at any point of time the users will see only a consistent view of all the objects – and all of them in a “Valid” state.
Well, actually, editions allow us to achieve this concept. We make all the changes in a new edition, and expose the new edition to the clients only when all the objects are valid.
We start this post’s example at the same point we ended the previous post. We have two editions and four editioned objects. In the V1 edition one of the objects – the PEOPLE_DL package body – is actual, and the other three objects are inherited from the OR$BASE edition:
Now we want to change the PEOPLE_DL spec, and we already know that the safe way to do it online is by using a new edition.
But something is very wrong with this picture. Recall the following statement from the previous post:
By definition, when we are in the context of a specific edition, we see and use the objects that are actual in this session and the inherited objects from ancestor editions, but never objects from descendant editions.
This observation may seem trivial, but in my opinion it’s the cornerstone of EBR. This is what lets us apply the new or changed code in the privacy of a new edition, where no client is exposed to the new version until we want to expose it.
In the picture, the PEOPLE_DL package body from V1 and the APP_MGR package body from ORA$BASE refer to the spec from V2, and this violates the “privacy rule”.
It means that whenever an object becomes actual in some edition, all its dependent objects must become actual in this edition as well. In our case, the correct picture is this:
Now, I have good news, bad news, very bad news, and really good news.
The good news is that this actualization of dependent objects happens automatically.
The bad news is that it happens too late. It doesn’t happen when we actualize the object, but only when the dependent objects are used (just like with regular revalidation), and that means we cannot count on the automatic actualization in an online upgrade scenario.
Very Bad News
The very bad news (in my opinion, of course) is that once we actualize an object in the new edition, we get a false and very misleading picture from the data dictionary views, until the dependent objects are actualized as well:
- By looking at the USER_OBJECTS view it seems that we still inherit the dependent objects from ancestor editions, although this is impossible under the EBR rules.
- There is no indication that the dependent objects became invalid as a result of the actualization.
- The dependencies from the dependent objects to the object we’ve just actualized disappear from the USER_DEPENDENCIES view.
All of this is a direct consequence of the fact that the actualization of the dependent objects is delayed.
Really Good News
So what is the really good news?
That once we know and understand this behavior, it’s easy to deal with it.
In the next post I’ll show how, as well as examples for everything described in this post.
For other parts of the EBR series, please visit the index page.