mysql事务

什么是事务

事务是一组操作,组成这组操作的各个单元,要不全都成功要不全都失败,这个特性就是事务。

事务的四大特性ACID

原子性(Atomicity)

原子性指的就是 MySQL 中的包含事务的操作要么全部成功、要么全部失败回滚,因此事务的操作如果成功就必须要全部应用到数据库,如果操作失败则不能对数据库有任何影响。

一致性(Consistency)

一致性指的是一个事务在执行前后其状态一致。比如A和B加起来的钱一共是 1000 元,那么不管A和B之间如何转账,转多少次,事务结束后两个用户的钱加起来还得是 1000,这就是事务的一致性。

持久性(Durability)

持久性指的是一旦事务提交,那么发生的改变就是永久性的,即使数据库遇到特殊情况比如故障的时候也不会产生干扰。

隔离性(Isolation)

当多个事务同时进行时,就有可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read) 的情况,为了解决这些并发问题,提出了隔离性的概念。

脏读

事务A读取了事务B更新后的数据,但是事务B没有提交,然后事务B执行回滚操作,那么事务A读到的数据就是脏数据。

不可重复读

事务A进行多次读取操作,事务B在事务A多次读取的过程中执行更新操作并提交,提交后事务A读到的数据不一致。

幻读

事务A将数据库中所有学生的成绩由A->B,此时事务B手动插入了一条成绩为A的记录,在事务A更改完毕后,发现还有一条记录没有修改,那么这种情况就叫做出现了幻读。

4种隔离级别

未提交读(read uncommited):

未提交读指的是一个事务在提交之前,它所做的修改就能够被其他事务所看到。允许脏读。

提交读(read commited):

已提交读指的是一个事务在提交之后,它所做的变更才能够让其他事务看到。oracle等数据库默认都是改级别(不重复读)。

可重复读(repeatable read):

可重复读指的是一个事务在执行的过程中,看到的数据是和启动时看到的数据是一致的。未提交的变更对其他事务不可见。InnoDB默认级别,在SQL标准中,该级别消除了不可重复读,但是还存在幻读的可能。

串行读(serializable):

顾名思义是对于同一行记录,写会加写锁,读会加读锁。读写相互阻塞,当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

事务级别查询和设置

设置事务级别

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

查询事务级别

SELECT @@global.tx_isolation;

SELECT @@session.tx_isolation;

SELECT @@tx_isolation;

举例

脏读例子:

session1:

mysql> select @@tx_isolation;

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

| @@tx_isolation  |

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

| REPEATABLE-READ |

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

1 row in set (0.00 sec)

mysql> insert into user(name) value('p');

Query OK, 1 row affected (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into user(name) value('iu');

Query OK, 1 row affected (0.00 sec)

session2:

mysql> select @@tx_isolation;

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

| @@tx_isolation  |

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

| REPEATABLE-READ |

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

1 row in set (0.00 sec)

mysql> select * from user;

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

| id | name |

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

|  1 | p    |

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

1 row in set (0.00 sec)

session3:(出现了脏读)


mysql> set session transaction isolation level read uncommitted;

Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation;

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

| @@tx_isolation   |

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

| READ-UNCOMMITTED |

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

1 row in set (0.00 sec)

mysql> select * from user;

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

| id | name |

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

|  1 | p    |

|  2 | iu   |

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

2 rows in set (0.00 sec)

总结

隔离级别由低到高是:未提交读 < 已提交读 < 可重复读 < 串行化

隔离级别越高,越能够保证数据的完整性和一致性,但是对并发的性能影响越大。大多数数据库的默认级别是读已提交(Read committed),比如 Sql Server、Oracle ,但是 MySQL 的默认隔离级别是 可重复读(repeatable-read)

# mysql 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×