-
Notifications
You must be signed in to change notification settings - Fork 105
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
sqlpage should close open transactions after each HTTP request #711
Comments
This was also reported in #695 |
I don't think SQLPage should try to "fix" the connection. Rather the problem should be reported and connection recycled (close/open). If I'm not wrong there are two cases to get into such situation:
The second case is more interesting since ideally the developer should be able to handle such cases. |
I think the best option for users is just to launch a What do you think ? |
We could also add a configuration option to disable the connection pooler completely, which would close the connection after each request, guaranteeing no lingering transactions. This would also be useful to people connecting to an external connection pooler. |
I like disabling the connection pooler - entirely and/or just for some endpoints. Besides the transaction handling this will also fix hanging temp tables and whatever other session data kept within the connection. Issuing a ROLLBACK is a hacky thing, imo. I know Oracle is not supported atm, but it has nested transactions which makes rollback more challenging. BTW, why don't you like recycling the connection on errors? |
@vtzi I had seen these issues as tangential, but I'm glad you're bringing attention to it. If they're related issues, all the better. I had assumed SQLPage would offer an
I think the "hanging" temporary tables are directly related to transaction handling. If developers can control transactions, then we can control table drops.
For me, personally, knowing the "rules" of SQLPage is sufficient. Connection pooling is good, lack of opinions is good, and I am happy hand-managing transactions as-needed. I prefer the "try and ROLLBACK" approach. After refreshing myself with sqlx, I have come to appreciate that SQLPage is non-opinionated. "Have connection, will query" is a good baseline because it returns transaction control to the sql scripts. |
Bringing this from one of the related discussions. It looks like each sql implementation has its own opinions. Postgres will automatically throw away the transaction, but sqlite wants to soldier on. https://www.postgresql.org/docs/7.3/plpgsql-errors-and-messages.html
https://www.sqlite.org/lang_transaction.html
|
I implemented automatic rollback of opened transaction before returning a connection to the pool. This way, you cannot get a connection with a half-finished transaction in progress when you start executing a new page. Can you test it and confirm everything works like you would expect ? Here is a pre-release linux binary. You can also get prereleases from I also discovered and fixed two related bugs in the process: https://github.com/sqlpage/SQLPage/blob/main/CHANGELOG.md#0320-unreleased |
This is not the proper way to handle errors in the SQL scripts, imo. It kind of fixes only errors within explicit multistatement transactions.
(Not all databases have Postgresql
Postgres has That said - it's your decision. Just have in mind that error handling will bite again sooner or later. |
I see what you mean... For the first point, there is indeed a performance penalty to running rollback, but it's an order of magnitude lower than discarding the connection. I think they are bound to transactions in sqlite too: sqlite> BEGIN; CREATE TEMPORARY TABLE t(x); ROLLBACK;
sqlite> select * from t;
Parse error: no such table: t and in mssql too:
This leaves mysql, where they explicitly mention it as a limitation... About additional session state: I think that's a problem all the time, not particularly when an error occurs. If we close the connection after an error occurs, an attacker can cause a denial of service by just repeatedly making invalid requests that will close database connections faster than we can open new ones... |
Ok, I'm reopening this :) I changed the implementation, to run a rollback only after an error occurs, and separately added an optional Please let me know what you think ! |
Looks great, thank you! There is small error in the docs here: sqlpage/on_disconnect.sql - shouldn't it be |
You are right, thank you! I fixed the docs. |
Discussed in #710
Originally posted by bever1337 November 25, 2024
Following example 11: https://sql.datapage.app/component.sql?component=form
I've created a sql script that creates a temporary table, copies to it, and then merges from the temporary table to the permanent table.
Typically, I use 'ON COMMIT DROP' when making temporary tables. On my second upload, sqlpage throws the error that my temporary table already exists. I kill the server, then put
begin
andcommit
as the first and last lines of my sql script. I test again, and get a similar error. Sometimes I receive postgres transaction warnings, ex beginning before committing.Finally, I add
commit; begin
andcommit
as the first and last lines. This works, but means I've thrown away a transaction I wasn't managing.How should users work with sqlpage transactions? Is there a way to align transactions with request lifecycles?
This pseudo code seems to work:
Judiciously beginning and ending every sqlpage script with begin and commit negates the need for commit;begin; and commit; in some files. Not sure which is best.
The text was updated successfully, but these errors were encountered: