<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 3.4\. 事務 _事務_是所有數據庫系統的一個基本概念。一次事務的要點就是把多個步驟捆綁成一個單一的、 不成功則成仁的操作。其它并發的事務是看不到在這些步驟之間的中間狀態的,并且如果發生了一些問題, 導致該事務無法完成,那么所有這些步驟都完全不會影響數據庫。 比如,假設一個銀行的數據庫包含各種客戶帳戶的余額,以及每個分行的總余額。 假設我們要記錄一次從 Alice 的帳戶到 Bob 的帳戶的金額為 $100.00 的支付動作。 那么,完成這個任務的簡單到極點的 SQL 命令像下面這樣: ``` UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice'; UPDATE branches SET balance = balance - 100.00 WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice'); UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob'; UPDATE branches SET balance = balance + 100.00 WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob'); ``` 這些命令的細節在這兒并不重要;重要的是這里牽涉到了好幾個獨立的更新來完成這個相當簡單的操作。 銀行官員會希望要么所有這些更新全部生效,要么全部不起作用。我們當然不希望一次系統崩潰就導致 Bob 收到 100 塊不是 Alice 支付的錢,也不希望 Alice 老是不花錢從 Bob 那里拿到物品。我們需要保證: 如果在操作的過程中出了差錯,那么所有這些步驟都不會發生效果。 把這些更新組合成一個_事務_就給予我們這樣的保證。事務被認為是_原子的_: 從其它事務的角度來看,它要么是全部發生,要么完全不發生。 我們還需要保證:一旦一個事務完成并且得到數據庫系統的認可,那么它必須被真正永久地存儲, 并且不會在隨后的崩潰中消失。比如,如果我們記錄到了一個 Bob 撤單的動作, 那么我們不希望僅僅在他走出銀行大門之后的一次崩潰就會導致對他的帳戶的扣減動作消失。 一個事務型數據庫保證一個事務所做的所有更新在事務發出完成響應之前都記錄到永久的存儲中(也就是磁盤)。 事務型數據庫的另外一個重要的性質和原子更新的概念關系密切:當多個事務并發地運行的時候, 每個事務都不應看到其它事務所做的未完成的變化。比如,如果一個事務正忙著計算所有分行的余額總和, 那么它不應該包括來自 Alice 的分行的扣帳和來自 Bob 分行的入帳,反之亦然。所以事務必須是黑白分明的, 不僅僅體現在它們在數據庫上產生的永久影響上,而且體現在它們運轉時的自身的可視性上。 一個打開的事務所做的更新在它完成之前是無法被其它事務看到的,而到提交的時候所有更新同時可見。 在PostgreSQL里,一個事務是通過把 SQL 命令用`BEGIN`和`COMMIT` 命令包圍實現的。因此我們的銀行事務實際上看起來像下面這樣: ``` BEGIN; UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice'; -- 等等 COMMIT; ``` 如果在該事務的過程中,我們決定不做提交(可能是我們剛發現 Alice 的余額是負數), 那么我們可以發出`ROLLBACK`而不是`COMMIT`命令, 那么到目前為止我們的所有更新都會被取消。 PostgreSQL 實際上把每個 SQL 語句當做在一個事務中執行來看待。 如果你沒有發出`BEGIN`命令,那么每個獨立的語句都被一個隱含的`BEGIN` 和(如果成功的話)`COMMIT`包圍。一組包圍在`BEGIN`和`COMMIT` 之間的語句有時候被稱做_事務塊_。 > **Note:** 一些客戶端庫自動發出`BEGIN`和`COMMIT`, 因此你可能不需要特意請求就可以獲得事務塊的效果。查看你使用的接口的文檔。 我們可以通過使用_保存點_的方法,在一個事務里更加精細地控制其中的語句。 保存點允許你選擇性地拋棄事務中的某些部分,而提交剩下的部分。在用`SAVEPOINT` 定義了一個保存點后,如果需要,你可以使用`ROLLBACK TO`回滾到該保存點。 則該事務在定義保存點到 ROLLBACK TO 之間的所有數據庫更改都被拋棄, 但是在保存點之前的修改將被保留。 在回滾到一個保存點之后,這個保存點仍然保存著其定義,所以你可以回滾到這個位置好幾次。 當然,如果你確信你不需要再次回滾到一個保存點,那么你可以釋放它,這樣系統可以釋放一些資源。 要記住:釋放或者回滾到一個保存點都會自動釋放在其后定義的所有保存點。 所有這些都發生在一個事務塊內部,所以所有這些都不可能被其它事務會話看到。 當且僅當你提交了這個事務塊,這些提交了的動作才能以一個單元的方式被其它會話看到, 而回滾的動作完全不會被看到。 記得我們的銀行數據庫嗎? 假設我們從 Alice 的帳戶上消費 $100.00 ,然后給 Bob 的帳戶進行加款, 稍后我們發現我們應該給 Wally 的賬號加款。那么我們可以像下面這樣使用保存點: ``` BEGIN; UPDATE accounts SET balance = balance - 100.00 WHERE name = 'Alice'; SAVEPOINT my_savepoint; UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Bob'; -- 呀!加錯錢了,應該用 Wally 的賬號 ROLLBACK TO my_savepoint; UPDATE accounts SET balance = balance + 100.00 WHERE name = 'Wally'; COMMIT; ``` 這個例子當然是實在太簡單了,但是通過使用保存點,我們可以對事務塊有大量的控制。 并且,`ROLLBACK TO`是除了事務全部回滾,重新來過之外, 唯一可以用于重新控制一個因錯誤而被系統置于退出狀態事務的方法。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看