473,801 Members | 2,437 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Cursors and Transactions, why?

Why must a cursor be defined in an open transaction? Obviously there's
a good reason, but I can't figure it out. On a high level, what would
be involved in allowing a cursor to outlive the transaction that
created it?

Cursors seem as if they have some nice performance benefits (esp. if
you're not using all rows found), but their usefulness drops
considerably since you must leave a transaction open.

eric
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to ma*******@postg resql.org

Nov 23 '05 #1
18 3367
On Apr 5, 2004, at 6:44 PM, Joe Conway wrote:
Eric Ridge wrote:
Why must a cursor be defined in an open transaction? Obviously
there's a good reason, but I can't figure it out. On a high level,
what would be involved in allowing a cursor to outlive the
transaction that created it?


Historically I think it was because the memory was released at the end
of the current transaction (i.e. allocations were made in
TopTransactionC ontext). But as of 7.4, cursors *can* outlive
transactions:
http://www.postgresql.org/docs/curre...l-declare.html

WITH HOLD
WITHOUT HOLD


holy cow! This is fantastic. I had no idea. <short pause> ooh, and
I see FETCH, in 7.4, supports absolute positioning. Must upgrade.

thanks!

eric
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 23 '05 #2
Eric Ridge wrote:
Why must a cursor be defined in an open transaction? Obviously there's
a good reason, but I can't figure it out. On a high level, what would
be involved in allowing a cursor to outlive the transaction that created
it?


Historically I think it was because the memory was released at the end
of the current transaction (i.e. allocations were made in
TopTransactionC ontext). But as of 7.4, cursors *can* outlive transactions:
http://www.postgresql.org/docs/curre...l-declare.html

WITH HOLD
WITHOUT HOLD

WITH HOLD specifies that the cursor may continue to be used after
the transaction that created it successfully commits. WITHOUT HOLD
specifies that the cursor cannot be used outside of the transaction that
created it. If neither WITHOUT HOLD nor WITH HOLD is specified, WITHOUT
HOLD is the default.

HTH,

Joe
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faqs/FAQ.html

Nov 23 '05 #3
Eric Ridge wrote:
Why must a cursor be defined in an open transaction? Obviously there's
a good reason, but I can't figure it out. On a high level, what would
be involved in allowing a cursor to outlive the transaction that
created it?
Because the transaction is what protects the rows that build the result
set from being removed by vacuum. In PostgreSQL, a cursor is a running
query executor just sitting in the middle of its operation. If the
underlying query is for example a simple sequential scan, then the
result set is not materialized but every future fetch operation will
read directly from the base table. This would obviously get screwed up
if vacuum would think nobody needs those rows any more.

Cursors seem as if they have some nice performance benefits (esp. if
you're not using all rows found), but their usefulness drops
considerably since you must leave a transaction open.


And now you know why they are so good if you don't use all rows. This
benefit I think goes away if you use Joe Conway's suggestion of WITH HOLD.
Jan

--
#============== =============== =============== =============== ===========#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#============== =============== =============== ====== Ja******@Yahoo. com #
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Nov 23 '05 #4
On 4/6/04 10:54 AM, "Jan Wieck" <Ja******@yahoo .com> wrote:
Cursors seem as if they have some nice performance benefits (esp. if
you're not using all rows found), but their usefulness drops
considerably since you must leave a transaction open.


And now you know why they are so good if you don't use all rows. This
benefit I think goes away if you use Joe Conway's suggestion of WITH HOLD.


I tried using WITH HOLD in the following case (using an ecpg C program):

foreach row in table A
update table B with value from table A
commit once every 10,000 updates
forend

I created a cursor on table A. Without WITH HOLD, obviously I got an error
on the next TABLE A fetch because the COMMIT closed the cursor. I added
'WITH HOLD' to the cursor. On the first COMMIT, the application hung. I
assume the COMMIT would have completed after some period of time, but I
didn't wait that long.

There are 20 million rows in table A and 60 million in table B (one to many
relationship).

Is this hang on COMMIT when using WITH HOLD to be expected? Is there a way
around it? I don't think it's reasonable put the entire 60 million updates
in a single transaction. The kludge solution I implemented was to write out
all the data I needed from table A to a file, then read that file and update
table B.

Wes
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 23 '05 #5
<we****@syntegr a.com> writes:
Is this hang on COMMIT when using WITH HOLD to be expected?
Yes. WITH HOLD is not magic, it just makes a materialized copy of the
SELECT result. If you're talking about a multi-million-row result,
it's gonna take awhile.
The kludge solution I implemented was to write out all the data I
needed from table A to a file, then read that file and update table B.


In theory at least, that should not be any faster than a WITH HOLD
cursor, since you're effectively replicating the same functionality
outside the database ...

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to ma*******@postg resql.org

Nov 23 '05 #6
On Apr 6, 2004, at 11:54 AM, Jan Wieck wrote:
Eric Ridge wrote:
Why must a cursor be defined in an open transaction? Obviously
there's a good reason, but I can't figure it out. On a high level,
what would be involved in allowing a cursor to outlive the
transaction that created it?
Because the transaction is what protects the rows that build the
result set from being removed by vacuum. In PostgreSQL, a cursor is a
running query executor just sitting in the middle of its operation.


That's a good thing to know.
If the underlying query is for example a simple sequential scan, then
the result set is not materialized but every future fetch operation
will read directly from the base table. This would obviously get
screwed up if vacuum would think nobody needs those rows any more.


Is vacuum the only thing that would muck with the rows?
Cursors seem as if they have some nice performance benefits (esp. if
you're not using all rows found), but their usefulness drops
considerably since you must leave a transaction open.


And now you know why they are so good if you don't use all rows. This
benefit I think goes away if you use Joe Conway's suggestion of WITH
HOLD.


Okay, so WITH HOLD is actually materializing the entire resultset
(sequential scan or otherwise)? If that's true, you're right, some of
the benefits do go away.

I need to setup a 7.4 test server and play with this some, and figure
out if the benefits are really what I want them to be. I do appreciate
the insight into how cursors work... it helps a lot!

eric
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 23 '05 #7
On 4/6/04 3:55 PM, "Tom Lane" <tg*@sss.pgh.pa .us> wrote:
The kludge solution I implemented was to write out all the data I
needed from table A to a file, then read that file and update table B.


In theory at least, that should not be any faster than a WITH HOLD
cursor, since you're effectively replicating the same functionality
outside the database ...


Except for the "out of memory" thing...

Are you saying that once the first COMMIT completed, all COMMIT's after that
would function at normal speed - only the first one has to save the result
set?

Wes
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Nov 23 '05 #8
<we****@syntegr a.com> writes:
On 4/6/04 3:55 PM, "Tom Lane" <tg*@sss.pgh.pa .us> wrote:
In theory at least, that should not be any faster than a WITH HOLD
cursor, since you're effectively replicating the same functionality
outside the database ...
Except for the "out of memory" thing...


What "out of memory thing"? The tuplestore code is perfectly capable of
spilling to disk --- in fact the usual performance gripe against it has
to do with spilling too soon, because sort_mem is set too small.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 23 '05 #9
Eric Ridge wrote:
On Apr 6, 2004, at 11:54 AM, Jan Wieck wrote:
And now you know why they are so good if you don't use all rows. This
benefit I think goes away if you use Joe Conway's suggestion of WITH
HOLD.


Okay, so WITH HOLD is actually materializing the entire resultset
(sequential scan or otherwise)? If that's true, you're right, some of
the benefits do go away.


Keep in mind that the tuplestore stays in memory as long as it fits
within sort_mem kilobytes. And you can do:

set sort_mem to <some_large_num ber>;

prior to COMMIT, and then

set sort_mem to default;

after COMMIT, as long as you can afford the memory use. A bit ugly, but
it might come in handy ;-)

Joe

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Nov 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
9033
by: Alban Hertroys | last post by:
Oh no! It's me and transactions again :) I'm not really sure whether this is a limitation of psycopg or postgresql. When I use multiple cursors in a transaction, the records inserted at the start of the transaction aren't visible to those later on in that transaction (using a different cursor). Attached is a simplified example (the except's are a bit blunt, I know) of what I'm trying to do. In reality, the different cursors are...
19
5767
by: Dave Anderson | last post by:
Can anyone point me to a good resource for learning cursors in MSSQL? Thanks Dave
22
10677
by: T.S.Negi | last post by:
Hi All, I want to avoid using cursors and loops in stored procedures. Please suggest alternate solutions with example (if possible). Any suggestion in these regards will be appreciated. Thanks in advance, T.S.Negi
5
2300
by: Mark Harrison | last post by:
In the program testlibpq.c, these five SQL statements are executed: res = PQexec(conn, "BEGIN"); res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database"); res = PQexec(conn, "FETCH ALL in myportal"); res = PQexec(conn, "CLOSE myportal"); res = PQexec(conn, "END"); Is this just to illustrate how to create transactions and cursors, or is there some material difference between trimming the program down to just:
5
6192
by: Todd Huish | last post by:
I have noticed something disturbing when retrieving datasets over a relatively slow line (multiple T1). I am looking at about 25 seconds to retrieve 500 rows via a php-odbc link. This same select from the cli is for all intents practicaly instantaneous. After much research I discovered that PHP by default uses a dynamic cursor type which can be quite a bit slower than a forward only cursor. BTW I have been searching forward only/read...
6
2512
by: a | last post by:
Hello, I am doing some multithreading in an MDI app, and I can't seem to get the cursor to stay as an Hourglass. I call: Cursor.Current = cursors.wait at the beginning of my routing, and set it back to cursors.default when the thread ends (using a callback)
10
17379
by: Just Me | last post by:
Does Me.Cursor.Current=Cursors.WaitCursor set the current property of Me.Cursor to Cursors.WaitCursor And Me.Cursor.Current=Cursors.Default set the Me.Current property to something (default) stored in Me.Cursor. Or is Cursors.Default some process wide cursor shape? What is a correct statement?
7
3554
by: H. Williams | last post by:
I know the .Net Cursor class doesn't work with color cursors. So I'm currently using the LoadCursorFromFile API with reflection to set color cursors: here is my code: public static extern IntPtr LoadCursorFromFile( string fileName ); IntPtr hwdCursor= LoadCursorFromFile( "color.cur" ); myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
1
6698
by: Dima Kuchin | last post by:
Hello, I was trying to find the information about when and where should I use cursors in DB2, no luck. Maybe you can point me to some article that describes just that (or tell me which page is it in DB2 SQL reference book, if it's there)? Or maybe you can post a short answer here, if there's no dedicated article? Another question would be about scrollable cursors (just found out about their existence) - what performance gains will I...
0
9698
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9556
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10295
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10271
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9105
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7593
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6832
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5486
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4263
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.