当前位置:Gxlcms > 数据库问题 > mysql的事务

mysql的事务

时间:2021-07-01 10:21:17 帮助过:5人阅读

| BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1}

在默认设置下,MySQL中的事务是默认提交的。如需对某些语句进行事务控制则使用START TRANSACTION或者BEGIN开始一个事务比较方便。这样事务结束之后可以自动回到自动提交的方式。

下面示例演示一个简单的事务,功能为更新表中的一条记录,为保证数据从一个一致性状态更新到另外一种一致性状态,因此采用事务完成更新过程,如果更新失败或者其他原因可以使用回滚。此实例执行时对应的MySQL默认隔离级别为REPEATABLE-READ。

技术分享
#查看MySQL隔离级别
mysql> show variables like tx_isolation;
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.33 sec)


#创建测试需要的表,主要存储引擎为InnoB
mysql> use company;
Database changed
mysql> create table test_1(id int,username varchar(20)) engine=InnoDB;
Query OK, 0 rows affected (0.67 sec)

mysql> insert into test_1 values(1,petter),(2,bob),(3,allen),(4,aron);
Query OK, 4 rows affected (0.17 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from test_1;
+------+----------+
| id   | username |
+------+----------+
|    1 | petter   |
|    2 | bob      |
|    3 | allen    |
|    4 | aron     |
+------+----------+
4 rows in set (0.00 sec)

#开启一个事务
mysql> begin;
Query OK, 0 rows affected (0.02 sec)

#更新一条记录
mysql> update test_1 set username=test where id = 1;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#提交事务
mysql> commit;
Query OK, 0 rows affected (0.06 sec)

#发现记录已经更改生效
mysql> select * from test_1;
+------+----------+
| id   | username |
+------+----------+
|    1 | test     |
|    2 | bob      |
|    3 | allen    |
|    4 | aron     |
+------+----------+
4 rows in set (0.00 sec)

#开启另外一个事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update test_1 set username=petter where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test_1;
+------+----------+
| id   | username |
+------+----------+
|    1 | petter   |
|    2 | bob      |
|    3 | allen    |
|    4 | aron     |
+------+----------+
4 rows in set (0.00 sec)

#回滚事务
mysql> rollback;
Query OK, 0 rows affected (0.13 sec)

#此时发现数据已经回滚
mysql> select * from test_1;
+------+----------+
| id   | username |
+------+----------+
|    1 | test     |
|    2 | bob      |
|    3 | allen    |
|    4 | aron     |
+------+----------+
4 rows in set (0.00 sec)
View Code

3. MySQL事务隔离级别

SQL标准定义了四种隔离级别,指定了事务中哪些数据改变其他事务可见,哪些数据改变其他事务不可见,低级别的隔离级别可以支持更高的并发处理,同时占用的系统资源更少。

查看MySQL隔离级别:

SHOW VARIABLES LIKE tx_isolation;

事务隔离级别可以使用以下语句设置:

#未提交读
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#提交读
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
#可重复读
SET GLOBAL TRANSACTION ISOLATION LEVEL  REPEATABLE READ;  
#可串行化
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

3.1 READ-UNCOMMITTED(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。因为其性能也不比其他级别高很多,因此此隔离级别实际应用中很少使用,读取未提交的数据被称为脏读(Dirty Read)。

脏读示例如下:

3.2 READ-COMMITTED(读取提交内容)

这是大多数数据库系统的默认隔离级别,但并不是MySQL默认的隔离级别。其满足了隔离的简单定义,一个事务从开始到提交前所做的任何改变都是不可见的,事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理期间可能会有新的数据提交导致数据改变,所以同一查询可能返回不同的结果。此级别导致的不可重复读示例如下所示:

3.3 REPEATABLE -READ(可重读)

这是MySQL的默认事务隔离级别,能确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。理论上会导致幻读(Phantom Read)。例如第一个事务对一个表中 的数据进行了修改,这种修改涉及表中的全部数据行。同时第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行。InnoDB和Falcon存储引擎通过多版本并发控制(Multi_Version Concurrency Control,MVCC)机制解决了该问题。

InnoDB存储引擎MVCC机制:

3.3 SERIALIZABLE(可串行化)

mysql的事务

标签:

人气教程排行