亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解PostgreSQL事務管理

發布時間:2021-11-08 16:07:57 來源:億速云 閱讀:135 作者:iii 欄目:關系型數據庫

本篇內容介紹了“怎么理解PostgreSQL事務管理”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、The Transaction System

README

src/backend/access/transam/README
The Transaction System
======================
事務系統
PostgreSQL's transaction system is a three-layer system.  The bottom layer
implements low-level transactions and subtransactions, on top of which rests
the mainloop's control code, which in turn implements user-visible
transactions and savepoints.
PostgreSQL的事務分為3層,底層實現了低層次的事務和子事務,在其頂上駐留主循環控制代碼,
而主循環實現了用戶可見性事務和保存點.
The middle layer of code is called by postgres.c before and after the
processing of each query, or after detecting an error:
        StartTransactionCommand
        CommitTransactionCommand
        AbortCurrentTransaction
Meanwhile, the user can alter the system's state by issuing the SQL commands
BEGIN, COMMIT, ROLLBACK, SAVEPOINT, ROLLBACK TO or RELEASE.  The traffic cop
redirects these calls to the toplevel routines
        BeginTransactionBlock
        EndTransactionBlock
        UserAbortTransactionBlock
        DefineSavepoint
        RollbackToSavepoint
        ReleaseSavepoint
respectively.  Depending on the current state of the system, these functions
call low level functions to activate the real transaction system:
        StartTransaction
        CommitTransaction
        AbortTransaction
        CleanupTransaction
        StartSubTransaction
        CommitSubTransaction
        AbortSubTransaction
        CleanupSubTransaction
在處理查詢的前后或者檢測到錯誤時,postgres.c會調用中間層的代碼:
        StartTransactionCommand
        CommitTransactionCommand
        AbortCurrentTransaction
在此期間,通過執行BEGIN/COMMIT/ROLLBACK/SAVEPOINT/ROLLBACK TO/RELEASE命令改變系統狀態.
調度程序會把這些調用重定向至相應的頂層例程上.
        BeginTransactionBlock
        EndTransactionBlock
        UserAbortTransactionBlock
        DefineSavepoint
        RollbackToSavepoint
        ReleaseSavepoint
依賴于當前的系統狀態,這些函數調用底層函數激活真正的事務系統:
        StartTransaction
        CommitTransaction
        AbortTransaction
        CleanupTransaction
        StartSubTransaction
        CommitSubTransaction
        AbortSubTransaction
        CleanupSubTransaction
Additionally, within a transaction, CommandCounterIncrement is called to
increment the command counter, which allows future commands to "see" the
effects of previous commands within the same transaction.  Note that this is
done automatically by CommitTransactionCommand after each query inside a
transaction block, but some utility functions also do it internally to allow
some operations (usually in the system catalogs) to be seen by future
operations in the same utility command.  (For example, in DefineRelation it is
done after creating the heap so the pg_class row is visible, to be able to
lock it.)
另外,在事務內,調用CommandCounterIncrement增加命令計數,這可以讓未來的命令可以看到
在同一個事務中先前命令的影響.
注意該動作由CommitTransactionCommand在事務塊內部完成每個查詢后自動完成,
但某些工具函數同樣會內部實現此功能以允許某些操作(通常在系統目錄中)可被未來同樣的工具命令看到.
(比如,在DefineRelation,在創建堆后已完成,因此pg_class中的行已可見,并能執行鎖定)
For example, consider the following sequence of user commands:
舉個例子,考慮下面一組用戶命令:
1)        BEGIN
2)        SELECT * FROM foo
3)        INSERT INTO foo VALUES (...)
4)        COMMIT
In the main processing loop, this results in the following function call
sequence:
在主處理循環,會形成下面函數調用序列:
     /  StartTransactionCommand;     -- middle
    /       StartTransaction;         -- bottom
1) <    ProcessUtility;                 << BEGIN
    \       BeginTransactionBlock;    -- top
     \  CommitTransactionCommand;    -- middle
    /   StartTransactionCommand;    -- middle
2) /    PortalRunSelect;                << SELECT ...
   \    CommitTransactionCommand;    -- middle
    \       CommandCounterIncrement;
    /   StartTransactionCommand;    -- middle
3) /    ProcessQuery;                   << INSERT ...
   \    CommitTransactionCommand;    -- middle
    \       CommandCounterIncrement;
     /  StartTransactionCommand;    -- middle
    /   ProcessUtility;                 << COMMIT
4) <        EndTransactionBlock;    -- top
    \   CommitTransactionCommand;    -- middle
     \      CommitTransaction;        -- bottom
The point of this example is to demonstrate the need for
StartTransactionCommand and CommitTransactionCommand to be state smart -- they
should call CommandCounterIncrement between the calls to BeginTransactionBlock
and EndTransactionBlock and outside these calls they need to do normal start,
commit or abort processing.
該例子想表達的意思是StartTransactionCommand和CommitTransactionCommand需要具備狀態智能
-- 在BeginTransactionBlock/EndTransactionBlock之間需調用CommandCounterIncrement,
在這些調用之外,它們需要執行常規的start,commit或abort處理.
Furthermore, suppose the "SELECT * FROM foo" caused an abort condition. In
this case AbortCurrentTransaction is called, and the transaction is put in
aborted state.  In this state, any user input is ignored except for
transaction-termination statements, or ROLLBACK TO <savepoint> commands.
而且,假定"SELECT * FROM foo"出錯,導致需要abort,那么會調用AbortCurrentTransaction(bottom),
事務狀態為aborted狀態.事務處于這個狀態,除了事務終止語句或者ROLLBACK TO <savepoint>命令外,所有用戶輸入都會被忽略.
Transaction aborts can occur in two ways:
事務取消的情況有兩種:
1) system dies from some internal cause  (syntax error, etc)
   內部原因,如語法錯誤等.
2) user types ROLLBACK
   用戶類型的ROLLBACK.
The reason we have to distinguish them is illustrated by the following two
situations:
區分事務取消的原因如下兩例所示:
        case 1                                  case 2
        ------                                  ------
1) user types BEGIN                     1) user types BEGIN
2) user does something                  2) user does something
3) user does not like what              3) system aborts for some reason
   she sees and types ABORT                (syntax error, etc)
In case 1, we want to abort the transaction and return to the default state.
In case 2, there may be more commands coming our way which are part of the
same transaction block; we have to ignore these commands until we see a COMMIT
or ROLLBACK.
第一種情況,用戶希望取消事務并返回到默認狀態.
第二種情況,在同一個事務塊中,可能會有更多的命令進入,需要忽略這些命令直至COMMIT/ROLLBACK.
Internal aborts are handled by AbortCurrentTransaction, while user aborts are
handled by UserAbortTransactionBlock.  Both of them rely on AbortTransaction
to do all the real work.  The only difference is what state we enter after
AbortTransaction does its work:
* AbortCurrentTransaction leaves us in TBLOCK_ABORT,
* UserAbortTransactionBlock leaves us in TBLOCK_ABORT_END
內部的事務取消通過AbortCurrentTransaction(bottom)處理,而用戶取消通過UserAbortTransactionBlock(top)處理.
它們都需要依賴AbortTransaction(bottom)來處理實際的工作,不同的地方是在AbortTransaction后進入的狀態不同:
* AbortCurrentTransaction進入TBLOCK_ABORT
* UserAbortTransactionBlock進入TBLOCK_ABORT_END
Low-level transaction abort handling is divided in two phases:
* AbortTransaction executes as soon as we realize the transaction has
  failed.  It should release all shared resources (locks etc) so that we do
  not delay other backends unnecessarily.
* CleanupTransaction executes when we finally see a user COMMIT
  or ROLLBACK command; it cleans things up and gets us out of the transaction
  completely.  In particular, we mustn't destroy TopTransactionContext until
  this point.
底層事務取消處理分為兩個階段:
* 一旦感知事務已失敗,則馬上執行AbortTransaction,需要釋放所有的共享資源(比如鎖等)以便不影響其他后臺進程.
* 在用戶發出COMMIT/ROLLBACK時執行CleanupTransaction;清理現場并完整的跳出事務.
  特別地,在這個點上才需要銷毀TopTransactionContext
Also, note that when a transaction is committed, we don't close it right away.
Rather it's put in TBLOCK_END state, which means that when
CommitTransactionCommand is called after the query has finished processing,
the transaction has to be closed.  The distinction is subtle but important,
because it means that control will leave the xact.c code with the transaction
open, and the main loop will be able to keep processing inside the same
transaction.  So, in a sense, transaction commit is also handled in two
phases, the first at EndTransactionBlock and the second at
CommitTransactionCommand (which is where CommitTransaction is actually
called).
同時,注意如果事務已提交,必須要馬上關閉,而是進入TBLOCK_END狀態,
這意味著在查詢完成后執行CommitTransactionCommand,事務才會關閉.
這種區別很微妙,但很重要,因為控制已在事務開啟的情況下從xact.c代碼中跳出,主循環仍在相同的主事務中.
因此,在某種意義上來說,事務提交存在兩個階段,首先EndTransactionBlock(top),其次CommitTransactionCommand(middle).
(CommitTransactionCommand是實際調用CommitTransaction的地方)
The rest of the code in xact.c are routines to support the creation and
finishing of transactions and subtransactions.  For example, AtStart_Memory
takes care of initializing the memory subsystem at main transaction start.
xact.c的剩余代碼是用于支持創建和結束事務和子事務的例程.
比如AtStart_Memory在主事務開啟時處理初始化內存子系統.

TransactionState結構體

/*
 *    transaction states - transaction state from server perspective
 */
typedef enum TransState
{
    TRANS_DEFAULT,                /* idle */
    TRANS_START,                /* transaction starting */
    TRANS_INPROGRESS,            /* inside a valid transaction */
    TRANS_COMMIT,                /* commit in progress */
    TRANS_ABORT,                /* abort in progress */
    TRANS_PREPARE                /* prepare in progress */
} TransState;
/*
 *    transaction block states - transaction state of client queries
 *
 * Note: the subtransaction states are used only for non-topmost
 * transactions; the others appear only in the topmost transaction.
 */
typedef enum TBlockState
{
    /* not-in-transaction-block states */
    TBLOCK_DEFAULT,                /* idle */
    TBLOCK_STARTED,                /* running single-query transaction */
    /* transaction block states */
    TBLOCK_BEGIN,                /* starting transaction block */
    TBLOCK_INPROGRESS,            /* live transaction */
    TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
    TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
    TBLOCK_END,                    /* COMMIT received */
    TBLOCK_ABORT,                /* failed xact, awaiting ROLLBACK */
    TBLOCK_ABORT_END,            /* failed xact, ROLLBACK received */
    TBLOCK_ABORT_PENDING,        /* live xact, ROLLBACK received */
    TBLOCK_PREPARE,                /* live xact, PREPARE received */
    /* subtransaction states */
    TBLOCK_SUBBEGIN,            /* starting a subtransaction */
    TBLOCK_SUBINPROGRESS,        /* live subtransaction */
    TBLOCK_SUBRELEASE,            /* RELEASE received */
    TBLOCK_SUBCOMMIT,            /* COMMIT received while TBLOCK_SUBINPROGRESS */
    TBLOCK_SUBABORT,            /* failed subxact, awaiting ROLLBACK */
    TBLOCK_SUBABORT_END,        /* failed subxact, ROLLBACK received */
    TBLOCK_SUBABORT_PENDING,    /* live subxact, ROLLBACK received */
    TBLOCK_SUBRESTART,            /* live subxact, ROLLBACK TO received */
    TBLOCK_SUBABORT_RESTART        /* failed subxact, ROLLBACK TO received */
} TBlockState;
/*
 *    transaction state structure
 */
typedef struct TransactionStateData
{
    FullTransactionId fullTransactionId;    /* my FullTransactionId */
    SubTransactionId subTransactionId;    /* my subxact ID */
    char       *name;            /* savepoint name, if any */
    int            savepointLevel; /* savepoint level */
    TransState    state;            /* low-level state */
    TBlockState blockState;        /* high-level state */
    int            nestingLevel;    /* transaction nesting depth */
    int            gucNestLevel;    /* GUC context nesting depth */
    MemoryContext curTransactionContext;    /* my xact-lifetime context */
    ResourceOwner curTransactionOwner;    /* my query resources */
    TransactionId *childXids;    /* subcommitted child XIDs, in XID order */
    int            nChildXids;        /* # of subcommitted child XIDs */
    int            maxChildXids;    /* allocated size of childXids[] */
    Oid            prevUser;        /* previous CurrentUserId setting */
    int            prevSecContext; /* previous SecurityRestrictionContext */
    bool        prevXactReadOnly;    /* entry-time xact r/o state */
    bool        startedInRecovery;    /* did we start in recovery? */
    bool        didLogXid;        /* has xid been included in WAL record? */
    int            parallelModeLevel;    /* Enter/ExitParallelMode counter */
    bool        chain;            /* start a new block after this one */
    struct TransactionStateData *parent;    /* back link to parent */
} TransactionStateData;
typedef TransactionStateData *TransactionState;

“怎么理解PostgreSQL事務管理”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

启东市| 宜兰市| 桐梓县| 吴堡县| 靖宇县| 宝丰县| 东方市| 锡林郭勒盟| 海南省| 商河县| 肥东县| 通道| 石门县| 会昌县| 东辽县| 固原市| 阿图什市| 宿松县| 神木县| 泌阳县| 富平县| 六安市| 鹿邑县| 普兰县| 贡嘎县| 乌鲁木齐市| 珲春市| 临桂县| 玛多县| 瑞丽市| 广德县| 磐安县| 张家口市| 小金县| 潮安县| 溆浦县| 镇康县| 三亚市| 荔浦县| 四会市| 张北县|