Session vs transaction
Starts when
Client connects
BEGIN
Ends when
Client disconnects
COMMIT
or ROLLBACK
Explicit control
❌ No
✅ Yes
Can be nested
❌ No
✅ Yes (via savepoints)
Scope of temp objects
Session-wide
Depends on transaction
ACID guarantees
❌ No
✅ Yes
When client connects to Postgres the session automatically starts, there are no explicit commands in SQL for this. How to check open sessions:
SELECT * FROM pg_stat_activity;
For example the session will be started for this command
psql -h localhost -p 5437 -U postgres -d postgres
Explicit Transaction Control
BEGIN; -- Start transaction
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- If everything looks good
COMMIT; -- Save changes
-- Or, if something went wrong
ROLLBACK; -- Discard changes
📌 This is explicit transaction control — you decide when the transaction starts and ends.
Savepoints (Nested Transactions)
You can also use savepoints to manage parts of a transaction:
BEGIN;
INSERT INTO logs (message) VALUES ('Start');
SAVEPOINT before_error;
-- Simulate error
INSERT INTO logs (message) VALUES ('Error occurred');
-- Rollback to savepoint
ROLLBACK TO before_error;
COMMIT;
This gives you fine-grained control within a single transaction.
Multiple Transactions in One Session
A PostgreSQL session can run many transactions, one after another.
Each transaction is isolated from the next, unless you explicitly share state using temporary tables, GUCs, or other session-level constructs.
🧪 Example: Multiple Transactions in One Session
-- Transaction 1
BEGIN;
INSERT INTO accounts (id, balance) VALUES (1, 100);
COMMIT;
-- Transaction 2
BEGIN;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
COMMIT;
-- Transaction 3
BEGIN;
DELETE FROM accounts WHERE id = 1;
ROLLBACK; -- Changes discarded
✅ Each transaction is explicitly started with
BEGIN
and ended withCOMMIT
orROLLBACK
.
After each transaction, the session is ready to start a new one.
Best Practice
Use session-scoped features (like temporary tables or
SET LOCAL
) only if you're using session pooling (e.g., HikariCP orpgBouncer
insession
mode).Prefer transaction pooling when possible for better scalability and stateless operations.
Always assume transactions are isolated, but sessions can retain state.
Breakdown: Spring Boot + Hibernate + PostgreSQL
1. Database Session (Connection)
A session in PostgreSQL is a TCP connection from the client (your app) to the database.
In Spring Boot, connections are usually pooled using HikariCP, Tomcat JDBC, or pgBouncer.
So, sessions are reused — not created for every transaction.
2. Hibernate Session (EntityManager
)
EntityManager
)Hibernate’s
Session
orEntityManager
is a wrapper over the JDBC connection.It can be bound to a transaction and reused within the same request or method.
It is not the same as a PostgreSQL session.
3. JPA Transaction
A JPA transaction corresponds to a SQL transaction (
BEGIN
,COMMIT
,ROLLBACK
).Each
@Transactional
method in Spring opens a new transaction on the same session (connection) if it’s already open.So, multiple transactions can run on the same session.
📌 Example: Spring Boot Code
@Service
public class AccountService {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
Account from = entityManager.find(Account.class, fromId);
Account to = entityManager.find(Account.class, toId);
from.setBalance(from.getBalance().subtract(amount));
to.setBalance(to.getBalance().add(amount));
entityManager.merge(from);
entityManager.merge(to);
}
}
What happens under the hood?
Spring checks if there's an existing transaction:
If not, it starts a new transaction (
BEGIN
).
It uses a connection from the connection pool (e.g., HikariCP).
The transaction ends with
COMMIT
(orROLLBACK
on error).The connection is returned to the pool, but not closed — it can be reused.
🧪 Real-World SQL Flow
Assuming two calls to transferMoney()
in the same thread:
-- Connection from pool (session PID = 12345)
BEGIN;
UPDATE accounts SET balance = ... WHERE id = 1;
UPDATE accounts SET balance = ... WHERE id = 2;
COMMIT;
BEGIN;
UPDATE accounts SET balance = ... WHERE id = 3;
UPDATE accounts SET balance = ... WHERE id = 4;
COMMIT;
✅ Both transactions run on the same session (PID 12345).
🧠 Connection Pooling Behavior
HikariCP
Reuses connections (sessions) across transactions in the same thread
pgBouncer (transaction mode)
May not reuse the same session for multiple transactions
pgBouncer (session mode)
Reuses the same session for the entire connection lifetime
⚠️ In
pgBouncer
transaction mode, temporary tables or session variables won't work across transactions — because each transaction may run on a different session.
Last updated
Was this helpful?