If I have a package variable in Oracle (8), and it is modified (incremented) in a function that is called from multiple triggers, is it possible that the function is called multiple times at once?
Specifically, we have sequence numbers within a business transaction, so we have a function that returns the next number in a sequence for a particular session, and then a function that creates an increments a package variable representing the sequence number. Basically, the function is something like:
function get_seq_num return number is
ret number;
begin
if g_seq_num is not null then
ret := g_seq_num;
g_seq_num := g_seq_num + 1;
else
g_seq_num := 1;
end if;
return ret;
end get_seq_num;
It appears that 2 triggers attempt to log the same seq_num for a given transaction, and I can’t quite work out why (unless they run concurrently, which I thought they wouldn’t).
**NOTE1: For the record, this is legacy code I’ve inherited, and am probably not in a position to change it irrespective of how bad a practice it is….
** NOTE2: Because I don’t think it is possible for the function to be executing multiple times concurrently, I am looking into whether the record_seq_num can possibly be updated anywhere else….
I think the answer to your question is sort of, yes.
Each database session gets its own copy of package variables. They are not shared between sessions. What you’ve described is NOT a safe way to create a sequence. If you have one session that hits that function a number of times, its copy of the package variable will be incremented, but another session will not. So it’s possible that session A will return 1, 2, 3 … and then session B will return 1.
Furthermore, your package variable will be discarded when the session closes or the package gets recompiled.
Here is an Ask Tom question on “Global variable across different sessions“
You should be using an Oracle sequence.