Postgres non-blocking call to another procedure within a procedure? - postgresql

My company has several clients/scenario combos worked on by different instances of the same java program. Once the java programs posts data to the database, each calls process_data(client, scenario) that further processes the data.
Occasionally, we have to reprocess the posted data for all the programs. I have created a redo procedure that figures out what arguments were used by all the programs of a given target_date and runs process_data(client, scenario).
It works fine. But, the redo procedure calls process_data one-by-one and I'd like to run each call in parallel. There is no risk of locking, as process_data normally runs in parallel when the java programs kick them off and there hasn't been an issue.
Here's what I mean in pseudo plpgsql code:
CREATE OR REPLACE PROCEDURE redo_data(target_date date)
LANGUAGE plpgsql
AS $procedure$
DECLARE
-- cursor that determines what needs re-doing.
list_what_to_redo cursor(carg_target_date);
begin
for redo in list_what_to_redo(target_date)
loop
-- I'd like this call to not block.
call process_data(redo.client, redo.scenario);
end loop;
-- Maybe wait here for all the non-blocking calls to finish.
END;
$procedure$
;
Is something like this possible? I know I can create something elaborate, like another java program that reads a job table with arguments to call and then creates a thread for each job and runs proces_data(), etc... But I was hoping to avoid doing something like that.
Several articles suggest dblink might help, but I don't know what to call. The exec calls look like blocking calls(?). There is an asynchronous dblink_send_query, but that is for queries. (Perhaps I can wrap process_data inside a table function and use dblink_send_query(myconn, "select wrapped_process_data(client, scenario)")
Thanks.

Related

does every procedure call create a recursive session in oracle

I'm trying to solve a case of constant ora--00018 "maximum open sessions exceeded" crashes even though sessions parameter in set to 1500, during those crushes number of v)session entries is sometimes 50 % off v$ resource_limit. current_utilization value of sessions parameter. So we suspect there are a lot of recursive sessions being made and that quickly brings A DB Server down. I know that triggers can cause a lot off recursive sessions . Does every procedure call create the same effect or are any specific kind of procedure that generate it. I tried to test by checking the current_utilization value before and after I ran a simple procedure and didn't see the difference. Maybe because my test procedure is too simple and too fast to notice. I've read this article http://tech.e2sn.com/oracle/oracle-internals-and-architecture/recursive-sessions-and-ora-00018-maximum-number-of-sessions-exceeded but it's not clear to me if every procedure is run on a different session . I'm using oracle 10g

call program in interactive sql as400

Is there a way to call a program from db2 interactive SQL in as400 (strsql)? this program receives an argument by reference and modify it's content. In CL, you simply call it like this:
call myprogram 12345
I need to be able to call it in interactive SQL, Is there any way or workaround to do this? like launching an OS command? for example in C you do system("your system command"). I couldn't find anything related to it.
STRSQL supports the SQL CALL statement.
The best option is to define the program as External SQL Stored procedure
--note
----- numeric-->zoned decimal
----- decimal-->packed decimal
CREATE PROCEDURE MYLIB.MYPROGRAM_SP
(IN number numeric(5,0))
LANGUAGE RPGLE
EXTERNAL NAME 'MYLIB/MYPROGRAM'
PARAMETER STYLE GENERAL;
Then you can
CALL MYLIB.MYPROGRAM_SP(12345)
Technically, every *PGM object on the IBM i is a stored procedure. You can call it without explicitly defining it as shown above. But assumptions are made about the parms in that case. It's much better to provide the DB with the interface definition.
Note that STRSQL is a 20 year old tool, it has various limitations including not supporting OUT or INOUT parameters of stored procedures.
A much better choice is to use the Run SQL Scripts component of IBM's Access Client Solutions (ACS)

Best way to track the progress of a long-running function (from outside) - PostgreSQL 11?

What is the best way to track progress of a
long-running function in PostgreSQL 11?
Since every function executes in a single transaction, even if the function writes to some "log" table no other session/transaction can see this output unless the function completes with SUCCESS.
I read about some attempts here but they are from 2010.
https://www.endpointdev.com/blog/2010/04/viewing-postgres-function-progress-from/
Also, this approach looks terribly inconvenient.
As of today what is the best way to track progress?
One approach that I know... is to turn the func to a procedure and then do partial commits in the SP. But what if I want to return some result set from the func... In that case I cannot turn it into a SP, right? So... how to proceed in that case?
Many thanks in advance.
NOTE: The function is written in PL/pgSQL, the most common procedural SQL language available in PostgreSQL.
I don't know that there's a great way to do it built-in to postgres yet, but there are a couple ways to achieve logging that will be visible outside of a function.
You can use the pg_background extension to run an insert in the background that will be visible outside of the function. This requires compiling and installing this extension.
Use dblink to connect to the same database and insert data. This will most likely require setting up some permissions.
Neither option is ideal, but hopefully one can work for you. Converting your function to a procedure may also work, but you won't be able to call the procedure from within a transaction.

PostgreSQL - how to determine whether a transaction is active?

Let me open by saying: yes, I am aware of Determine if a transaction is active (Postgres)
Unfortunately the sole answer to that question is far too specific to the use case provided, and doesn't actually indicate whether or not a transaction is active.
The select txid_current(); trick suggested by How to check for pending operations in a PostgreSQL transaction doesn't appear to work - I always get the same transaction ID from adjacent calls to that function. Possibly this is because I'm trying to test it from pgAdmin, which is transparently starting transactions...? (Note: I don't actually care whether there are any pending changes or active locks, so looking at pg_locks isn't helpful - what if nothing's been touched since the transaction was started?)
So: How can I determine in PostgreSQL PL/pgSQL code if a transaction is currently active?
One possible use case is: the SP/FN in question will be doing its own explicit transaction management, and calling it with a transaction already active will greatly interfere with that. I want to raise an error so that the coding mistake of calling this SP/FN in a transaction can be corrected.
There are other use cases, though.
Ideally what I'm looking for is an equivalent to MSSQL's ##TRANCOUNT (though I don't really care how deeply the transactions may be nested...)
Postgres runs PL/pgSQL inside the transaction. Thus you can't control transaction from inside PL/pgSQL. Code will look like:
begin;
select plpgsql_fn();
do '/*same any plpgsql*/';
end;
So answering your question:
If you have PL/pgSQL running ATM, you have your transaction active ATM...
Of course you can do some trick, like starting/ending work over dblink or such. but then you can check select txid_current(); over the dblink successfully...
If you want to determine if there have been any data modifications in your transaction, call txid_current_if_assigned(). It returns NULL if nothing has been modified yet.
If you only want to know if you are inside some transaction, you can save yourself the trouble, because you always are.
Before PostgreSQL v11, you cannot use transaction control statements in a function.
I haven't found a clean way to do that, but you can always call BEGIN and if it succeeds it means there is no transaction in progress (don't forget to rollback). If it fails with "there is already a transaction in progress" this means you are within transaction (better not to rollback then).

Running one procedure from another in background using T-SQL

I need to execute one procedure from another in background\asynchronously.
procedure1:
CREATE PROCEDURE procedure1
WITH EXECUTE AS OWNER
AS
BEGIN
//something happens here
EXEC procedure2
//something happens here
END
procedure2:
CREATE PROCEDURE procedure2
WITH EXECUTE AS OWNER
AS
BEGIN
WAITFOR DELAY '00:02'
END
I need procedure1 to execute without waiting for procedure2 to end. I've read this answer in other post:
There was once I tried to achieve this by wrapping the stored
procedure into Job, and then Calling the job in the procedure through
sp_start_job system sp. EXEC dbo.sp_start_job N'Job name' ;
but I don't understand it. Can anyone explain it to me, please? Cause it doesn't look like something advanced but I cannot achieve what I want.
They are referring to creating a SQL Agent Job. This is in its simplest a way to schedule scripts to be run on the server. Typically you would have scripts that need to be run every hour, day, week, etc and rather than run them manually you set up an Agent Job to run them automatically for you.
The Jobs all live in the SQL Server Agent section of your Object Explorer:
Once you have created the job, you can call it manually using sp_start_job. If you only want the job to run when you call it, simply create the job and don't assign a schedule.