首页 > 数据库 >(九)MySQL基础知识之 事务(commit, rollback,begin,set autocommit)

(九)MySQL基础知识之 事务(commit, rollback,begin,set autocommit)

时间:2022-10-20 20:34:57浏览次数:46  
标签:autocommit 事务 set rollback sec mysql 2020 +----+-----------+------------+-------

昨天说了下MySQL的正则表达式,今天我们来说下事务的基础知识。

  什么是MySQL的事务呢?

  事务是由一步或几步数据库操作序列组成逻辑执行单元,这一系列操作要么全部执行,要么全部放弃执行。  这里我们需要说下程序和事务的区别。

一段程序中可能包含多个事务(n步的数据库操作而构成的逻辑执行单元) ,很像进程和线程的关系。一个进程中可能包含多个线程。


   事务主要用于处理操作量大,复杂度高的数据。举例:人员管理系统中,删除一个人员,不仅需要删除人员的基本资料,也要删除和该人员相关的信息。

在数据库中,相当于不仅仅是删除一个id或者name,而是整个和id对应的数据。删除的这些数据库操作语句就构成了一个事务。

  1. MySQL中只有使用了 Innodb 数据库引擎的数据库或者表才支持事务(可以使用命令来查看你的数据库是什么引擎,都能支持哪些引擎)
  2. 事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行。
  3. 事务用来管理 insert update delete 语句(别的MySQL语句是管不了的)


下面我们说下满足事务的条件(ACID):

A: Atomicity  或称不可分割性

     一个事务(transaction) 中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback) 到事务开始前的状态,就像这个事务从来没有执行过一样。

C: Consistency 

    在事务开始之前和事务结束之后,数据库的完整性没有被破坏。表示写入的资料必须完全符合所有的预设规则。包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

I: Isolation  又称独立性

   数据库允许多个并发事务同时对其数据进行读写和修改的能力。隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

事务隔离分为不同级别: 

  1. 读未提交 Read uncommitted
  2. 读提交 read committed
  3. 可重复读 repeatable read
  4. 串行化 Serializable

D: Durability 持久性

     事务处理结束后,对数据的修改就是永久的。即便系统故障也不会丢失

这里我们需要注意的是:

在MySQL命令行的默认设置下,事务都是自动提交的,执行SQL语句后就会马上执行commit操作

因此要显示地开启一个事务必须使用命令 begin 或 start transaction 或者执行命令 set autocommit = 0 用来禁止使用当前会话的自动提交


下面说下 事务的控制语句:

begin 或 start transaction  显式地开启一个事务


commit 可以使用 commit work, 二者是等价的。commit会提交事务,并使已对数据库进行的所有修改成为永久性的。


rollback可以使用 rollback work 二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。


savepoint identifier, savepoint 允许在事务中创建一个保存点,一个事务中可以有多个savepoint


release savepoint identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常。ERROR 1305 (42000): SAVEPOINT identifier does not exist


rollback to identifier 把事务回滚到标记点


set transaction 用来设置事务的隔离级别: InnoDB 存储引擎提供事务的隔离级别有

read uncommitted

read committed

repeatable read

serializable


MySQL 事务处理主要有两种方法:

1.用 begin rollback commit 来实现

   begin 开始一个事务

   rollback 事务回滚

   commit 事务确认


2.直接用 set 来改变 MySQL的自动提交模式

   set autocommit = 0 禁止自动提交

   set autocommit = 1 开启自动提交


说了这么多,我们来写个实例: 这次我们新建一个数据库表来写

mysql> create table star (

 -> `id` int unsigned auto_increment,

 -> `name` varchar(100) not null,

 -> `time` date,

 -> `scores` int not null,

 -> `country` varchar(30),

 -> primary key (`id`)

 -> )engine= InnoDB default charset = utf8;

Query OK, 0 rows affected (0.07 sec)

在创建数据库表时,直接设置好数据库表的引擎为 InnoDB

来看下数据库表的信息:

mysql> show columns from star;

+---------+------------------+------+-----+---------+----------------+

| Field  | Type  | Null | Key | Default | Extra |

+---------+------------------+------+-----+---------+----------------+

| id | int(10) unsigned | NO  | PRI | NULL | auto_increment |

| name | varchar(100)  | NO  |  | NULL | |

| time | date  | YES |  | NULL | |

| scores | int(11) | NO  |  | NULL | |

| country | varchar(30) | YES |  | NULL | |

+---------+------------------+------+-----+---------+----------------+

5 rows in set (0.02 sec)

通过插入数据(insert into)来查看begin和rollback的用法:

mysql> begin

 -> ;

Query OK, 0 rows affected (0.00 sec)


mysql> insert into star (name,time,scores,country) values ("LG",now(),78,"中国");

Query OK, 1 row affected, 1 warning (0.02 sec)


mysql> select * from star;

+----+------+------------+--------+---------+

| id | name | time  | scores | country |

+----+------+------------+--------+---------+

| 1 | LG  | 2020-07-03 |  78 | 中国 |

+----+------+------------+--------+---------+

1 row in set (0.00 sec)


可以看出,成功向数据库中插入了一条语句,然后我们使用rollback语句进行回滚

mysql> rollback;

Query OK, 0 rows affected (0.01 sec)


mysql> select * from star;

Empty set (0.00 sec)

可以看出star数据库表的内容又是空的了


我们再看看commit的用法

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

事务开始,然后插入一条数据

mysql> insert into star (name,time,scores,country) values ("李大志",now(),88,"俄罗斯");

Query OK, 1 row affected, 1 warning (0.00 sec)

我们查询下数据库表:

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

+----+-----------+------------+--------+-----------+

2 rows in set (0.00 sec)

然后提交完成事务

mysql> commit;

Query OK, 0 rows affected (0.01 sec)


mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

+----+-----------+------------+--------+-----------+

2 rows in set (0.00 sec)

再查下数据,插入的数据还在,然后我们回滚下

mysql> rollback;

Query OK, 0 rows affected (0.00 sec)


mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

+----+-----------+------------+--------+-----------+

2 rows in set (0.00 sec)

commit后,即使运行回滚代码,数据也不会被回滚,因为已经commit了


这里我们需要着重点说下 set autocommit的用法

首先,我们需要先知道所在的表的autocommit值为多少,如果为0,则是禁止自动提交;

如果为1,是允许主动提交。

mysql> show variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit | ON  |

+---------------+-------+

1 row in set (0.01 sec)

可以看出来,数据库表是可以主动提交的。我们来将这个值设置为OFF

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

然后我们查看下autocommit的值

mysql> show variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit | OFF  |

+---------------+-------+

1 row in set (0.01 sec)

嗯,已经关闭了。然后我们怎么查看事务呢?

再创建一个终端B,一直输入命令到查询star表的内容

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

+----+-----------+------------+--------+-----------+

2 rows in set (0.00 sec)


在终端A中,输入begin,然后插入数据,此时在终端B中查询数据,看是否已经插入

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into star (name,time,scores,country) values ("葫芦",now(),77,"英国");

Query OK, 1 row affected, 1 warning (0.01 sec)

在终端A中查询下star表的内容:

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

| 5 | 葫芦 | 2020-07-03 |  77 | 英国 |

+----+-----------+------------+--------+-----------+

3 rows in set (0.00 sec)

是有id = 5的数据


在终端B中输入查询语句

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

+----+-----------+------------+--------+-----------+

2 rows in set (0.01 sec)

发现还是2条数据


然后在终端A中commit下

mysql> commit;

Query OK, 0 rows affected (0.00 sec)


在终端B中查看下数据:

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

| 5 | 葫芦 | 2020-07-03 |  77 | 英国 |

+----+-----------+------------+--------+-----------+

3 rows in set (0.00 sec)

也有数据了


如果我们设置 set autocommit = 1呢(开启自动提交),再重复下上面的步骤

mysql> set autocommit = 1;

Query OK, 0 rows affected (0.00 sec)


mysql> show variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit | ON |

+---------------+-------+

1 row in set (0.00 sec)


在终端A中begin后插入数据,然后在终端B中进行查看

mysql> 

mysql> begin;

Query OK, 0 rows affected (0.00 sec)


mysql> insert into star (name,time,scores,country) values ("王五子",now(),77,"挪威");

Query OK, 1 row affected, 1 warning (0.01 sec)


在终端B中,输入查询语句,查不到已经输入的值


mysql> commit;

Query OK, 0 rows affected (0.00 sec)

还是在终端A中commit后,终端B可以查到了

mysql> select * from star;

+----+-----------+------------+--------+-----------+

| id | name | time  | scores | country  |

+----+-----------+------------+--------+-----------+

| 2 | LG | 2020-07-03 |  78 | 中国 |

| 4 | 李大志 | 2020-07-03 |  88 | 俄罗斯 |

| 5 | 葫芦 | 2020-07-03 |  77 | 英国 |

| 6 | 王五子 | 2020-07-03 |  77 | 挪威 |

+----+-----------+------------+--------+-----------+

4 rows in set (0.00 sec)


这是为什么呢?那这个 set autocommit有什么意义呢?


今天先到这里

(九)MySQL基础知识之 事务(commit, rollback,begin,set autocommit)_测试

标签:autocommit,事务,set,rollback,sec,mysql,2020,+----+-----------+------------+-------
From: https://blog.51cto.com/u_11894/5780518

相关文章

  • set集合的union()函数 跟 typing.Union
     一、set的union()方法1.描述union()方法返回两个集合的并集,即包含了所有集合的元素,重复的元素只会出现一次  2.语法set.union(set1,set2...)set1--必......
  • JDBC各个详解-ResultSet基本使用以及遍历结果集
    JDBC各个详解-ResultSet基本使用ResultSet:结果集对象,封装查询结果next():游标向下移动一行getxxx():获取数据xxx:代表数据类型如:intgetInt() String......
  • .NET Core appsettings.json 取值
    本文主要介绍.NETCore中,通过appsettings.json配置文件获取数据库连接字符串。 1、在项目的根目录中创建appsettings.json文件{"MssqlConnectionString":"Server......
  • JDBC练习_delete、DDL语句和JDBC各个类详解_ResultSet_基本使用
    JDBC练习_delete、DDL语句:delete语句:删除一条记录1.练习:account表 删除一条记录publicstaticvoidmain(String[]args){//设sta为空Statement......
  • 【luogu CF1140F】Extending Set of Points(线段树分治)
    ExtendingSetofPoints题目链接:luoguCF1140F题目大意有一个点集,有一个扩展操作是加入符合条件的(x0,y0)直到不能加入位置。符合条件是原来(x0,y0)不存在而且存......
  • 小程序的this.data和this.setdata
    this.data是用来获取页面data对象的,而this.setData是用来更新界面的。用this.setData({})用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data的值(同步)。用thi......
  • How to get the return value of the setTimeout inner function in js All In One
    HowtogetthereturnvalueofthesetTimeoutinnerfunctioninjsAllInOne在js中如何获取setTimeout内部函数的返回值✅Promisewrap&Async/Await......
  • K8S之StatefulSet控制器
    无状态应用进程客户端的每次连接均可独立地处理,一次请求和响应即构成一个完整的事务,它们不受已完成的连接或现有其他连接的影响,且意外中断或关闭时仅需要重新建立连接即可,因......
  • 【Kubernetes】K8s笔记(九):DaemonSet 守护进程集
    目录0.Deployment有哪些不足1.使用YAML描述DaemonSet对象2.在Kubernetes里使用DaemonSet3.Taint和Toleration4.静态PodkubernetesDaemonSetdocs0.Dep......
  • K8S statefulset
       StatefulSet详解kubectlexplainsts.spec:主要字段解释replicas:副本数selector:那个pod是由自己管理的serviceName:必须关联到一个无头服务商template:定义pod模......