Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple cursors on single transaction not supported. #65

Closed
McAronDev opened this issue May 2, 2020 · 5 comments · Fixed by #259
Closed

Multiple cursors on single transaction not supported. #65

McAronDev opened this issue May 2, 2020 · 5 comments · Fixed by #259
Labels
bug Something isn't working
Milestone

Comments

@McAronDev
Copy link

  await sql.begin((tx:any)=>{
    return Promise.all([
      tx`select 1 as cursor, x from generate_series(1,4) as x`.cursor(async (row: any[])=>{
        console.log('cursor1' , JSON.stringify(row));
        await new Promise(resolve=>setTimeout(resolve, 2000));
      }),
      tx`select 2 as cursor, x from generate_series(101,104) as x`.cursor(async (row: any[])=>{
        console.log('cursor2' , JSON.stringify(row));
        await new Promise(resolve=>setTimeout(resolve, 1000));
      })
    ]);
  });

This code returns unexpected console output:

cursor1 {"cursor":1,"x":1}
cursor1 {"cursor":2,"x":101}
cursor1 {"cursor":2,"x":102}
cursor1 {"cursor":2,"x":103}
cursor1 {"cursor":2,"x":104}

is it possible to support simultaneous reading for multiple cursors in single transaction?

@McAronDev
Copy link
Author

Same behavior when using cursors without transactions but with limited pool size. When second cursor was created on same connection as first one reading from first cursor hangs, but first's cursor handler receives rows from second cursor.

@porsager
Copy link
Owner

porsager commented May 4, 2020

Hi @McAronDev

That's really interesting, I haven't thought about that use case when implementing cursors, so I would have to give it some more thought.

I'm currently very hung up with work, so it might be a little while before I can find the time to look closer.

@pauldraper
Copy link

pauldraper commented May 18, 2020

You can't run more than one query simultaneously in a transaction.

There is a bug here, but FYI, your first example can't ever really be done.

@McAronDev
Copy link
Author

McAronDev commented May 19, 2020

@pauldraper

You can't run more than one query simultaneously in a transaction.

Yes. But they should be queued. Since this lib does not provide separate cursor creation and it's fetching methods, i guess we should be able to reuse transaction while cursor is "paused" and until that all queries should be queued.

So in my example, there should be the following behavior:

  1. cursor1 created and start fetching. cursor2 creation is queued.
    DECLARE cursor1 CURSOR FOR select 1 as cursor, x from generate_series(1,4) as x; FETCH 1 FROM cursor1;
  2. received first row from cursor1. cursor1 paused for 2 seconds.
  3. cursor2 created and start fetching.
    DECLARE cursor2 CURSOR FOR select 2 as cursor, x from generate_series(101,104) as x; FETCH 1 FROM cursor2;
  4. received first row from cursor2. cursor2 paused for 1 second.
  5. cursor2 resumed
    FETCH 1 FROM cursor2;
  6. cursor2 received second row, and paused again for 1sec

... Following fetching order is not easy predictable=) but we should receive all rows from both cursors.

@pauldraper
Copy link

Sure, that makes sense.

@porsager porsager added the bug Something isn't working label Mar 23, 2021
@porsager porsager added this to the v2 milestone Sep 19, 2021
@porsager porsager mentioned this issue Jan 11, 2022
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants