zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [项目管理]如何写好项目验收材料
    [英语学习]英语高级口译证书考试 备查
    A1042 Shuffling Machine洗牌机器
    B1018锤子剪刀布
    B1012数字分类
    B1008数组元素循环右移问题
    B1046划拳
    B1026 程序运行时间
    B1016部分A+B
    B1011A+B和C
  • 原文地址:https://www.cnblogs.com/yanshw/p/11429959.html
Copyright © 2011-2022 走看看