zoukankan      html  css  js  c++  java
  • 【13】事务

    1、什么叫做事务?

    mysql中,事务其实是一个最小的不可分割的工作单元。事务能够保证一个业务的完整性。

    eg.银行转账:

    a要向b转出100元:a-->-100:

     update user set money=money-100 where name='a';

    b-->+100:

     update user set money=money+100 where name='b';

    实际的程序中,如果上述只有一条语句成功了,而另外一条没有执行成功的话,就会出现数据前后不一致。

    因此,多条sql语句,可能会有同时执行成功的要求,要么就同时失败。

    2、mysql中如何控制事务?(commit、rollback)

    mysql默认是开启事务的(自动提交)。

    mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            1 |
    +--------------+

    默认开启事务的作用是什么?

    当我们执行一个sql语句的时候,效果会立即体现出来,且不能回滚。

    mysql> create database bank;
    mysql> use bank;
    mysql> create table user(
        -> id int primary key,
        -> name varchar(20),
        -> money int
        -> );
    mysql> INSERT INTO user VALUES(1,'a',1000);

    事务回滚:撤销sql语句执行效果

    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    +----+------+-------+

    尽管使用rollback,user的数据还在,没有撤回。

    解决:设置mysql自动提交为false:

    mysql> set autocommit=0;
    mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            0 |
    +--------------+

    结果:

    mysql> INSERT INTO user VALUES(2,'b',1000);
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    |  2 | b    |  1000 |
    +----+------+-------+
    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    +----+------+-------+

    再一次插入数据:

    手动提交数据(commit),这时候再撤销是行不通的。(持久性产生效果,rollback无用了

    mysql> INSERT INTO user VALUES(2,'b',1000);
    mysql> commit;
    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    |  2 | b    |  1000 |
    +----+------+-------+

    自动提交

    @@autocommit=1

    手动提交

    commit;

    事务回滚

    rollback;

    转账:

    mysql> update user set money=money-100 where name='a';
    mysql> update user set money=money+100 where name='b';
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+
    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    |  2 | b    |  1000 |
    +----+------+-------+

    事务为我们提供了一个可以反悔的机会。

    3、手动开启事务:begin 和 start transaction

    还原自动提交设置:

    mysql> set autocommit=1;
    mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            1 |
    +--------------+

    begin; 或者 start transaction; 都可以帮我们手动开启一个事务。

    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |  1000 |
    |  2 | b    |  1000 |
    +----+------+-------+

    转账后:

    mysql> update user set money=money-100 where name='a';
    mysql> update user set money=money+100 where name='b';
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+

    此时,事务回滚没有被撤销,rollback无用(因为已设置成自动提交):

    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+

    再次转账:

    mysql> begin;
    mysql> update user set money=money-100 where name='a';
    mysql> update user set money=money+100 where name='b';
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   800 |
    |  2 | b    |  1200 |
    +----+------+-------+

    rollback之后:

    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+

    使用begin(start transaction)手动开启事务,事务可以回滚。

    mysql> start transaction;
    mysql> update user set money=money-100 where name='a';
    mysql> update user set money=money+100 where name='b';
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   800 |
    |  2 | b    |  1200 |
    +----+------+-------+
    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+

    事务开启之后,一旦commit提交,就不可以回滚(当前这个事务在提交的时候就结束了)。

    mysql> commit;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+
    mysql> rollback;
    mysql> select * from user;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | a    |   900 |
    |  2 | b    |  1100 |
    +----+------+-------+
  • 相关阅读:
    AirtestIDE这个隐藏的小助手,还没用过你就亏啦!
    不懂抓包也能做APP爬虫?1招教你爬取抖音流行歌名
    巧用bat文件做Airtest脚本的“批量运行”
    AirtestIDE1.2.4、1.2.5新版来袭!新增自动更新、iOS更多版本支持...
    NodeService Ensure that Node.js is installed and can be found in one of the PATH directories
    NET CORE通过NodeService调用js
    Java8 的 Stream API 的确牛X,但性能究竟如何呢?
    Java 生成二维码实战
    Java高并发之设计模式,设计思想
    NullPointerException 的处理新方式,Java14 真的太香了!
  • 原文地址:https://www.cnblogs.com/direwolf22/p/12695860.html
Copyright © 2011-2022 走看看