事务
事务是一组原子性的SQL语句,理解事务最常用的例子就是银行转账:
A转给B100元钱,这个存储过程包含:
- A账户钱减少100元
- B账户钱增加100元
如果执行完第一步的SQL语句,但是因为系统崩溃等原因,导致第二条SQL语句没能正常执行,那么两个账户的总钱数就莫名其妙的少了100元。因此我们需要引入事务的概念,让这两步操作合成为一个原子操作,只有当两步操作全部正确完成时,事务提交,改动生效,否则事务回滚,恢复为初始状态。
MySQL中使用事务
下面我们以例子的形式演示MySQL种事务的使用,表结构定义如下。
create table t_person(
person_id bigint auto_increment primary key,
name varchar(255)
);
下面例子我们使用事务插入数据。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t_person(name) values ("Tom");
Query OK, 1 row affected (0.00 sec)
mysql> insert into t_person(name) values ("Bob");
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.07 sec)
mysql> select * from t_person;
+-----------+------+
| person_id | name |
+-----------+------+
| 1 | Tom |
| 2 | Bob |
+-----------+------+
2 rows in set (0.00 sec)
在MySQL终端中,我们使用了begin和commit命令,这两个命令代表着事务的开始和结束。
在存储过程中使用事务
存储过程中,使用一下三条语句表示事务的开始,提交和回滚。
START TRANSACTION;
COMMIT;
ROLLBACK;
事务的隔离级别
我们知道数据库有一个线程安全问题,因此引入了锁的概念,锁主要分为:共享锁和排它锁。MySQL中可以显式的使用锁,但是除此之外还有隐式的锁。隐式锁通过隔离级别,由MySQL和存储引擎自动指定。这里我们主要介绍MySQL的隐式的锁和隔离级别。
数据库隔离级别
以下四个隔离级别依次递增。
READ UNCOMMITTED
最低的隔离级别,所有事务都能看到尚未提交的事务的执行结果(脏读问题)。
READ COMMITTED
一个事务从开始到提交前,所做的任何数据改变,都是不可见的,直到该事务提交。但是这还是存在一个问题,即一个执行过程中的事务会读到另一个已提交事务对数据的更改(不可重复读问题)。
REPEATABLE READ
该级别在一次事务中,读相同的某一条数据,只能读到相同的值。避免了不可重复读问题。但是,还是存在问题的,如果另一个事务执行了插入操作,那么新插入的值还是会被当前事务读到(幻读问题)。
该级别是MySQL默认的隔离级别。
SERIALIZABLE
最高隔离级别,解决上述三个问题,但是性能较差。
MySQL会根据设置的隔离级别,自动使用合适的锁机制,实现线程安全。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。