From: | Bob <luckyratfoot(at)gmail(dot)com> |
---|---|
To: | pgsql-general(at)postgresql(dot)org |
Subject: | pl/perl autonomous transactions question |
Date: | 2006-09-25 19:05:06 |
Message-ID: | 762e5c0609251205g4b31de9mbeb59ca0a8261d4c@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
I would like to use autonomous transactions for a large batch process and I
want this all encapsulated within stored procedures. I want to commit after
say every 15,000 records. The only way I have found to do this is to use the
perl DBI in my stored procedure to establish a new connection to the
database.
1. Is
there any way to tell the DBI connection to use the current credtials
just with a new connection?
2. Is there any way to get the spi call to create a new connection instead
of using the connection it is called with?
One issue I see with my current DBI solution is
I need to hard code or pass in as variables the connection
information. I would prefer not to have the password lying around in
plain site. Keep in mind this is a batch process not a something I
that is called manually where a user is
going to be entering their username and password in.
Any help or ideas would be great.
Below is a simple example to demonstrate.
CREATE TABLE test_values ( c1 SERIAL, c2 VARCHAR (200));
CREATE OR REPLACE FUNCTION proc_perl_test_insert() RETURNS VOID AS $$
use DBI;
my $db_host = 'localhost';
my $db_user = 'postgres';
my $db_pass = 'somepassword';
my $db_name = 'dev';
elog(NOTICE,"Executeing proc_perl_test_insert");
#Creates a new connection so that an autonomous transactions can take place
independent of main transaction.
#INSERT INTO test_values (c2) VALUES ('Autonomous Transaction') will commit
regardless if the calling transaction fails or is rolled back.
my $db = "DBI:PgPP:dbname=${db_name};host=${db_host}";
my $dbh=DBI->connect("DBI:PgPP:dbname=dev;host=localhost","postgres",
"c21993b");
if ($dbh)
{
my $sth = $dbh->prepare("INSERT INTO test_values (c2) VALUES
('Autonomous Transaction')");
$sth->execute();
}
#This inserts using spi_exec_query and will only commit if the calling
transaction commits.
for ($count=1; $count<2; $count++)
{
my $query = qq{
INSERT INTO test_values ( c2 )
VALUES ( 'Non Autonomous Transaction' )
};
my $rv = spi_exec_query($query);
}
$$ LANGUAGE plperlu;
--Now Test the pl/perl function from psql and use a outer transaction
START TRANSACTION;
SELECT proc_perl_test_insert();
ROLLBACK TRANSACTION;
SELECT * FROM test_values;
--HERE IS MY psql commands being run as you can see it does what I want in
that it commits my one statement but not the other
dev=# START TRANSACTION;
START TRANSACTION
Time: 0.000 ms
dev=# SElECT * FROM proc_perl_test_insert();
NOTICE: Running proc_perl_test_insert
proc_perl_test_insert
-----------------------
(1 row)
Time: 70.000 ms
dev=# ROLLBACK TRANSACTION;
ROLLBACK
Time: 0.000 ms
dev=# select * from test_values;
c1 | c2
---------+------------------------
2898364 | Autonomous Transaction
(1 row)
Time: 0.000 ms
dev=#
Regards,
Bob Henkel
From | Date | Subject | |
---|---|---|---|
Next Message | Nikolay Samokhvalov | 2006-09-25 20:17:35 | Re: What is the Best Postgresql Load Balancing Solution available ? |
Previous Message | Andrew Sullivan | 2006-09-25 18:23:26 | Re: in failed sql transaction |