PostgreSQL-事務與commit優化

基本概念

事務 Transaction 是 數據庫管理系統DBMS 執行過程當中的一個邏輯單元,是一個 sql命令組成的序列。html

其特色在於,當事務被提交DBMS後,DBMS須要確保全部的操做被完成;若是事務中有的操做沒有成功完成,那麼全部操做都將回滾,回滾到事務提交以前的狀態python

 

屬性

事務具備如下四個標準屬性sql

原子性:事務做爲一個總體被執行,至關於一個原子數據庫

一致性:確保修改先後數據庫都知足約束併發

隔離性:多個事務能併發執行,互不影響post

持久性:已被提交的事務對數據庫的修改應該永久保存在數據庫中優化

 

適用場景

某人在商店使用電子貨幣支付100元,包括如下兩個操做:spa

1. 消費者帳戶減小100元postgresql

2. 商家帳戶增長100元code

事務的做用就是保證這兩個操做要麼都發生,要麼都不發生,不然可能出現100元憑空消失。

 

事務控制

使用以下命令控制事務

begin 或者 begin transaction:開始一個事務

commit 或者 end transaction:提交事務,執行一系列sql

rollback:事務回滾

 

在開始一個事務後,除非遇到 commit 或者 rollback 命令,事務纔會被執行;

若是還沒遇到 commit 或者 rollback,數據庫發生異常,也會自動回滾。

 

注意,事務命令只能用於 insert、delete、update 操做,而其餘命令,好比建表、刪表,會被自動提交。

 

總結一下:事務須要手動開啓,手動提交;並且這種方式能提升操做效率。

 

實例

假設有以下表

id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

操做1:開始事務,從表中刪除年齡爲25的記錄,最後用rollback撤銷全部操做

runoobdb=# BEGIN;
DELETE FROM COMPANY WHERE AGE = 25;
ROLLBACK;

結果以下

id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

咱們發現原表沒有任何改變

 

操做2:開始事務,從表中刪除年齡爲25的記錄,最後用commit提交事務

runoobdb=# BEGIN;
DELETE FROM COMPANY WHERE AGE = 25;
COMMIT;

此時咱們發現表中age爲25的已刪除。

 

Python 示例

time.clock()
conn = psycopg2.connect(host='172.16.89.80',user="postgres",password="postgres",database="postgres")
cur = conn.cursor()
cur.execute("BEGIN TRANSACTION")        # 開始事務


if __name__=='__main__':
    for i in range(0,1000):
        cur.execute('INSERT INTO test(a, b, c, d) VALUES (%d, %d, %d, %d);'%(i, i, i, i))
    cur.execute('commit')         # 提交事務
    cur.close()
    conn.close()
    print(time.clock())

執行成功,耗時約 2s

 

繼續嘗試

上面手動開始了事務,後面我作了以下嘗試,發現耗時只有 1s      【commit 優化】

time.clock()
conn = psycopg2.connect(host='172.16.89.80',user="postgres",password="postgres",database="postgres")
cur = conn.cursor()


if __name__=='__main__':
    for i in range(0,1000):
        cur.execute('INSERT INTO test(a, b, c, d) VALUES (%d, %d, %d, %d);'%(i, i, i, i))
    conn.commit()
    cur.close()
    conn.close()
    print(time.clock())

執行了一系列sql,最後來個 commit,一樣執行成功,且耗時更少,我猜想是python自動開始了事務,以 commit 命令提交,無需手動開始。  【後續有空會驗證下這個猜想】

 

 

 

參考資料:

https://www.runoob.com/postgresql/postgresql-transaction.html

相關文章
相關標籤/搜索