• 数据库学习之事务


    数据库学习之事务

    数据库事务

      数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

     四个特性

    事务相关命令

    start transaction     开启事务
    Rollback  回滚事务,即撤销指定的sql语句(只能回退insert delete update语句)
    Commit 提交事务,提交未存储的事务
    savepoint保留点   事务处理中设置的临时占位符 你可以对它发布回退(与整个事务回退不同)
    

      

     简单示例

    我们在生活中,一个人给另一个人转钱。

    假如李四给王五转5000,李四的钱扣了,但是王五没有收到这样的情况发生了。

    准备

    create table account(id int,name varchar(20),balance double);
    
    insert into account value(2,"alex",10000);
    insert into account value(3,"lili",10000);
    

      

     转账实例:

    update account set balance=balance-5000 where name="xinyi";
    
    update account set balance=balance+5000 where name="lili";
    

      

    start transaction;  #开启事务
    update account set balance=balance-5000 where name="xinyi";  #xinyi的账户减5000(这里进行的操作是没有保存到数据库中的,如果你此时commit才会写入数据库)
    select * from account; #查询表
    rollback; #假设这里出现了网络问题,扣款失败,撤销前面的操作(撤销到开启事务或者上一次commit的地方)
    select * from account;   #再次查询表
    commit;   #提交整个事务
    

      

    pymysql中调用数据库启动事务

    # 导入pymysql模块
    import pymysql
    
    # 连接database
    conn = pymysql.connect(
        host="123.207.251.121",
        user="root",
        password="159357",
        db ="test",
        charset ="utf8")
    
    # 得到一个可以执行SQL语句的光标对象
    cursor = conn.cursor()  # 执行完毕返回的结果集默认以元组显示
    
    # 事务处理
    sql_0 = "insert into account value(4,'liurun',3400) "
    sql_1 = "update account set balance=balance-2000 where name='lili' "
    sql_2 = "update account set balance=balance+2000 where name='xinyi' "
    
    try:
        cursor.execute(sql_0)  # 插入一条数据
        conn.commit()
        cursor.execute(sql_1)  # lili账号减5000
        cursor.execute(sql_2)  # xinyi账号多5000
    except Exception as e:
        conn.rollback()  # 事务回滚
        print('事务处理失败', e)
    else:
        conn.commit()  # 事务提交
        print('事务处理成功', cursor.rowcount)
    
    
    # 关闭光标对象
    cursor.close()
    
    # 关闭数据库连接
    conn.close()
    

    结果:

    savepoint 保留点

    前面使用rollback回滚事务,不管你前面有多少操作,都会撤销操作

    如果前面有五十条操作,一下子回滚到最开始,那么肯定不合理,可不可以回滚到指定的操作上?

    你只需要给相应的操作取一个名字,相当于一个标识。

    设置标识点

    savepoint 标识名;

    回滚指定标识点

    rollback to 标识名;
    
    #开启事务
    start transaction;

    #第一次
    insert into account values(4,"name1",8000); savepoint insert1; select * from account; #第二次 insert into account values(4,"name2",3000); savepoint insert2; select * from account; #第三次 delete from account where id=2; savepoint delete1; select * from account; #第四次 delete from account where id=4; savepoint delete2; select * from account;

      

    原始数据:

    第一次:(依次执行)

     第二次:

    第三次:

    第四次:

     回滚到delete1:

     

     回滚到insert1:

     

  • 相关阅读:
    C# 发布和订阅2
    C#中的事件订阅与发布
    [PhaserJS] 鼠标事件
    在nsis中使用2个欢迎/完成页面图像
    NSIS 打包脚本基础
    PostgreSQL 如何比较两个表的定义是否一致
    P5333[JSOI2019]神经网络【dp,容斥】
    P8329[ZJOI2022]树【容斥,dp】
    P6803[CEOI2020]星际迷航【博弈论,dp,矩阵乘法】
    P8330[ZJOI2022]众数【根号分治】
  • 原文地址:https://www.cnblogs.com/-wenli/p/10413408.html
Copyright © 2020-2023  润新知