惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
量子位
雷峰网
雷峰网
宝玉的分享
宝玉的分享
V
Visual Studio Blog
博客园_首页
小众软件
小众软件
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
SegmentFault 最新的问题
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
PostgreSQL 0B000 Error: Causes and Solutions Complete Guide
umzzil nng · 2026-06-01 · via DEV Community

umzzil nng

PostgreSQL Error 0B000: invalid_transaction_initiation

PostgreSQL error 0B000 (invalid_transaction_initiation) occurs when your code attempts to start a transaction in a context where it is not permitted. This typically happens when nesting BEGIN statements inside an already-active transaction block, or trying to issue transaction control commands inside a regular PL/pgSQL function. Understanding this error is key to writing robust, production-grade PostgreSQL applications.


Top 3 Causes

1. Nested BEGIN Statements

PostgreSQL does not support true nested transactions in the standard sense. Calling BEGIN inside an already-open transaction block triggers a warning (or error depending on the client driver).

-- PROBLEMATIC: Nested BEGIN
BEGIN;
  INSERT INTO orders (customer_id, amount) VALUES (1, 100.00);
  BEGIN;  -- WARNING: there is already a transaction in progress
    INSERT INTO order_items (order_id, product) VALUES (1, 'widget');
  COMMIT;
COMMIT;

-- CORRECT: Use SAVEPOINT for partial rollback capability
BEGIN;
  INSERT INTO orders (customer_id, amount) VALUES (1, 100.00);

  SAVEPOINT sp_items;
  INSERT INTO order_items (order_id, product) VALUES (1, 'widget');

  -- Roll back only the inner operation if needed
  -- ROLLBACK TO SAVEPOINT sp_items;

  RELEASE SAVEPOINT sp_items;
COMMIT;

2. Transaction Control Inside a PL/pgSQL Function

Regular PL/pgSQL functions run within the caller's transaction context. Issuing COMMIT or ROLLBACK inside a function raises an error.

-- WRONG: COMMIT inside a regular function
CREATE OR REPLACE FUNCTION bad_func() RETURNS VOID AS $$
BEGIN
    INSERT INTO logs (msg) VALUES ('started');
    COMMIT;  -- ERROR: invalid transaction termination
END;
$$ LANGUAGE plpgsql;

-- CORRECT: Use a PROCEDURE (PostgreSQL 11+) for transaction control
CREATE OR REPLACE PROCEDURE good_proc()
LANGUAGE plpgsql AS $$
BEGIN
    INSERT INTO logs (msg, ts) VALUES ('step_1', NOW());
    COMMIT;  -- Valid inside a PROCEDURE

    INSERT INTO logs (msg, ts) VALUES ('step_2', NOW());
    COMMIT;
END;
$$;

-- Call with CALL, not SELECT
CALL good_proc();

3. ORM / Driver Autocommit Conflicts

Many client libraries (psycopg2, JDBC, SQLAlchemy) disable autocommit by default, silently opening a transaction. Manually issuing BEGIN on top of that causes conflicts.

-- Check if you're already inside a transaction
SELECT pg_current_xact_id_if_assigned() IS NOT NULL AS in_transaction;

-- Monitor active transactions on the server
SELECT
    pid,
    usename,
    state,
    now() - xact_start AS duration,
    left(query, 80) AS current_query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
  AND pid = pg_backend_pid();


Quick Fix Solutions

  1. Replace nested BEGIN with SAVEPOINT — use SAVEPOINT, ROLLBACK TO SAVEPOINT, and RELEASE SAVEPOINT for sub-transaction control.
  2. Convert functions to procedures — if you need COMMIT/ROLLBACK inside procedural code, migrate to CREATE PROCEDURE and call with CALL.
  3. Set autocommit = True at the driver level — let PostgreSQL manage transaction boundaries explicitly rather than relying on implicit behavior.
-- Safe transaction wrapper pattern
DO $$
BEGIN
    -- Always check state before manual BEGIN in scripts
    RAISE NOTICE 'Current xact id: %', txid_current();
END;
$$;


Prevention Tips

  • Define clear transaction boundaries in your application layer. Adopt a coding standard that mandates SAVEPOINT for nested logic and forbids raw BEGIN inside utility functions.
  • Enable warning-level logging in postgresql.conf (log_min_messages = warning) so that any implicit transaction warnings surface in your logs immediately, before they escalate into production errors.
-- Recommended postgresql.conf settings
-- log_min_messages = warning
-- client_min_messages = notice


Related Errors

Code Name Notes
25000 invalid_transaction_state Illegal operation for current tx state
25001 active_sql_transaction Command not allowed in active transaction
25P01 no_active_sql_transaction COMMIT/ROLLBACK outside any transaction
40001 serialization_failure Concurrency conflict, often seen alongside bad tx management

📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.