Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the consequences of not ending a database transaction?

I have found a bug in my application code where I have started a transaction, but never commit or do a rollback. The connection is used periodically, just reading some data every 10s or so. In the pg_stat_activity table, its state is reported as "idle in transaction", and its backend_start time is over a week ago.

What is the impact on the database of this? Does it cause additional CPU and RAM usage? Will it impact other connections? How long can it persist in this state?

I'm using postgresql 9.1 and 9.4.

like image 764
wolfcastle Avatar asked Nov 19 '15 22:11

wolfcastle


People also ask

What happens when a transaction ends?

A transaction ends when any of the following actions occurs: A user issues a COMMIT or ROLLBACK statement without a SAVEPOINT clause. In a commit, a user explicitly or implicitly requested that the changes in the transaction be made permanent. Changes made by the transaction are permanent and visible to other users only after a transaction commits.

What happens after a transaction completes in a database?

After a transaction completes, the database ensures through its recovery mechanisms that changes from the transaction are not lost. The use of transactions is one of the most important ways that a database management system differs from a file system.

What happens when a database fails after 20 updates?

For example, if a transaction starts updating 100 rows, but the system fails after 20 updates, then the database rolls back the changes to these 20 rows. The transaction takes the database from one consistent state to another consistent state.

Why is the database still running after a communication failure?

Following a communication failure, the database may still be running the submission and be unaware that the client disconnected. Checking the transaction state does not guarantee that an active transaction will not commit after being checked.


2 Answers

Since you only SELECT, the impact is limited. It is more severe for any write operations, where the changes are not visible to any other transaction until committed - and lost if never committed.

It does cost some RAM and permanently occupies one of your allowed connections (which may or may not matter).

One of the more severe consequences of very long running transactions: It blocks VACUUM from doing it's job, since there is still an old transaction that can see old rows. The system will start bloating.

In particular, SELECT acquires an ACCESS SHARE lock (the least blocking of all) on all referenced tables. This does not interfere with other DML commands like INSERT, UPDATE or DELETE, but it will block DDL commands as well as TRUNCATE or VACUUM (including autovacuum jobs). See "Table-level Locks" in the manual.

It can also interfere with various replication solutions and lead to transaction ID wraparound in the long run if it stays open long enough / you burn enough XIDs fast enough. More about that in the manual on "Routine Vacuuming".

Blocking effects can mushroom if other transactions are blocked from committing and those have acquired locks of their own. Etc.

You can keep transactions open (almost) indefinitely - until the connection is closed (which also happens when the server is restarted, obviously.)
But never leave transactions open longer than needed.

like image 156
Erwin Brandstetter Avatar answered Sep 26 '22 03:09

Erwin Brandstetter


There are two major impacts to the system.

The tables that have been used in those transactions:

  1. are not vacuumed which means they are not "cleaned up" and their statistics aren't updated which might lead to bad (=slow) execution plans
  2. cannot be changed using ALTER TABLE
like image 24
a_horse_with_no_name Avatar answered Sep 26 '22 03:09

a_horse_with_no_name