PostgreSQL-事務與commit優化


基本概念

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

其特點在於,當事務被提交DBMS后,DBMS需要確保所有的操作被完成;如果事務中有的操作沒有成功完成,那么所有操作都將回滾,回滾到事務提交之前的狀態

 

屬性

事務具有以下四個標准屬性

原子性:事務作為一個整體被執行,相當於一個原子

一致性:確保修改前后數據庫都滿足約束

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

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

 

適用場景

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

1. 消費者賬戶減少100元

2. 商家賬戶增加100元

事務的作用就是保證這兩個操作要么都發生,要么都不發生,否則可能出現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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM