美文网首页
java_事务(transaction)(DCL)

java_事务(transaction)(DCL)

作者: 走停2015_iOS开发 | 来源:发表于2021-01-20 16:11 被阅读0次
    1. 一个事务是一个完整的业务逻辑单元,不可再分 比如银行账户转账 从a账户向b账户转账1w,需要执行俩条update语句

      update t_act set balance = balance - 10000 where actno = 'act-001';
      update t_act set balance = balance + 10000 where actno = 'act-002';
      以上俩条DML语句必须同时成功 或者同时失败 不允许出现一条成功 一条失败
      要想保证以上俩条DML语句同时成功或者同时失败 那么就需要使用数据库的事务机制

    2. 和事务相关的语句只有DML语句(insert delete update)

      为什么 因为他们三个语句都是和数据库当中的数据相关的
      事务的存在是为了保证数据的完整性和安全性

    3. 假设所有业务都可以使用一条DML语句搞定 那就不需要事务
    4. 开启事务机制
    假设一个业务 需要先执行insert into 再执行一条update  最后执行delete 完成业务
    1.开启事务机制(开始)
    2.执行insert语句----insert....(这个执行成功之后,把这个执行记录到数据库操作记录中 并不会修改或添加硬盘上的数据)
    3.执行update语句---update...(把这个执行记录到数据库操作记录中 并不会修改或添加硬盘上的数据)
    4.执行delete语句---delete...(把这个执行记录到数据库操作记录中 并不会修改或添加硬盘上的数据)
    5.提交事务或者回滚事务
     > 5.1 提交事务:清空数据库操作记录 并且修改硬盘数据 commit
     > 5.2 回滚事务:清空数据库操作记录 但是不修改硬盘数据 rollback
    

    5.关于事务之间的隔离级别

    1.第一级别 读未提交(read uncommitted)
    对方事务还没有提交 我们当前事务可以读取对方未提交的数据
    读未提交存在脏读的现象 表示读到脏数据
    2.第二级别 读已提交
    对方事务已经提交之后数据 我方可以读取到
    存在不可重复读的现象
    3.第三级别 可重复读 
    读取的数据都是对方事务没有修改之前的数据 都是幻想数据
    4.第四级别 序列化读 串行化读
    解决了所有问题 但是效率低下
    >orcal数据库默认的隔离级别是 读已提交
    >mysql数据默认的隔离级别是 可重复读
    
    • 演示隔离级别
      //设置全局事务隔离级别
      mysql> set global transaction isolation level read uncommitted;
      //查看隔离级别
      mysql> select @@global.tx_isolation;
    //1. 演示read uncommitted
    1.1终端A :mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    +----+----------+     
    
    1.2.终端B :mysql> insert into t_stu(username) values ('SMITH');
     Query OK, 1 row affected (0.00 sec)  
      
    1.3.终端A :mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    |  7 | SMITH    |
    +----+----------+
    
    //2. 演示read committed;
    
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    +----+----------+
    
    mysql> insert into t_stu (username) values ('testq');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    +----+----------+
    
    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    |  8 | testq    |
    +----+----------+
    4 rows in set (0.00 sec)
    
    //3.演示repeatable read
    1、mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    |  8 | testq    |
    +----+----------+
    2、mysql> delete from t_stu;
    Query OK, 4 rows affected (0.00 sec)
    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)
    mysql> select *from t_stu;
    Empty set (0.00 sec)
    
    3、mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    |  8 | testq    |
    
    // 4.演示 serializable
    
    

    6.演示事务

    1.mysql事务默认情况是自动提交的(只要执行任意一条DML语句则提交一次)

    怎么关闭自动提交: start transaction

    create table t_stu(
    id int primary key auto_increment,
    username varchar(255)
    );
    insert into t_stu (username) values ('ww');
     select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    +----+----------+
    2 rows in set (0.00 sec)
    
    //回滚发现没有用
    mysql> rollback;
    Query OK, 0 rows affected (0.00 sec)
    

    2.使用start transaction; 关闭自动提交机制

    mysql> start transaction;
    Query OK, 0 rows affected (0.00 sec)
    mysql> insert into t_stu (username) values ('lisi');
    mysql> insert into t_stu (username) values ('wangwu');
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  3 | lisi     |
    |  4 | wangwu   |
    +----+----------+
    //查询发现已经有三条数据 但是实际硬盘上只有一条数据入下图所示(硬盘数据中实际数据)
    
    //回滚
    mysql> rollback;
    Query OK, 0 rows affected (0.00 sec)
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    +----+----------+
    
    //提交
    mysql> insert into t_stu (username) values ('wangwu');
    mysql> insert into t_stu (username) values ('rose');
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    
    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    
    //(commit相当于把数据持久化到硬盘里去了 无法回滚)
    mysql> rollback;
    Query OK, 0 rows affected (0.00 sec)
    mysql> select *from t_stu;
    +----+----------+
    | id | username |
    +----+----------+
    |  1 | ww       |
    |  5 | wangwu   |
    |  6 | rose     |
    +----+----------+
    3 rows in set (0.00 sec)
    
    
    硬盘数据中实际数据

    相关文章

      网友评论

          本文标题:java_事务(transaction)(DCL)

          本文链接:https://www.haomeiwen.com/subject/ekghzktx.html