事务 多条sql语句的集合,要么都成功,要么都失败,事务基于存储引擎提供(innodb) 事务的特性ACID A 原子性(atomicity):事务必须被视为一个不可分割的单元。 C 一致性(consistency):数据库从一种状态切换到另一种状态。 I 隔离性(isolation):事务在提交之前,对其他事务不可见。 D 持久性(durablity):一旦事务提交,所修改的数据永久保存到数据库。
开启事务 Start transaction Begin
回滚事务 Rollback
提交事务 Commit
查看自动提交状态 Show variables like ‘autocommit’ 开启第二次事务时,上一个事务将会被隐式提交 Set autocommit=0 关闭自动提交 =1 开启自动提交
查看自动提交状态 Show variables like ‘autocommit’ 开启第二次事务时,上一个事务将会被隐式提交 Set autocommit=0 关闭自动提交 =1 开启自动提交
事务的四种隔离级别 1.read uncommitted(未提交读) 2.read committed(已提交读) 3.repeatable read (可重复读) 4.serializable(可串行读)
设置隔离级别的命令 : SET SESSION TX_ISOLATION=‘READ-UNCOMMITTED/READ-COMMITTED/REPEATABLE READ/SERIALIZABLE’
1.未提交读: 多个事务同时进行,一个事务在未提交时执行操作,对于其他事务是可见的,未提交读会产生脏读的问题,
另开终端进入mysql 别名b事务表
A事务
B
A
事务B修改了数据,但还未提交,这时候事务A就读到被事务B修改的数据,事务B进行回滚,然后事务A再次读到的数据和刚刚的不一致,事务A读到的事务B未提交的哪行数据就是脏读; 2. 已提交读: 多数数据库都将已提交读设置为默认隔离级别(mysql不是),一个事务对数据表进行的操作, 提交以后才对其他事务可见。它解决了脏读的问题。但是它会产生不可重复读的问题;
事务A: mysql> SET SESSION TX_ISOLATION=‘READ-COMMITTED’; Query OK, 0 rows affected (0.00 sec)
mysql> BEGIN; Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM student1; ±—±---------+ | id | name | ±—±---------+ | 2 | zhangsan | | 3 | zhangsi | | 4 | zhangwu | | 5 | zhangliu | ±—±---------+ 4 rows in set (0.00 sec)
事务B: mysql> SET SESSION TX_ISOLATION=‘READ-COMMITTED’; Query OK, 0 rows affected (0.00 sec)
mysql> BEGIN; Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE student1 SET name=‘zhangqi’ WHERE id=5; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
事务A:查看 mysql> SELECT * FROM student1; ±—±---------+ | id | name | ±—±---------+ | 2 | zhangsan | | 3 | zhangsi | | 4 | zhangwu | | 5 | zhangliu | ±—±---------+ 4 rows in set (0.00 sec) 事务B没有提交的修改,我们在事务A当中看不到;
事务B:提交事务 mysql> COMMIT; Query OK, 0 rows affected (0.01 sec)
查看事务A: mysql> SELECT * FROM student1; ±—±---------+ | id | name | ±—±---------+ | 2 | zhangsan | | 3 | zhangsi | | 4 | zhangwu | | 5 | zhangqi | ±—±---------+ 4 rows in set (0.00 sec) 事务B提交了以后,事务A对提交结果可见,这样解决了未提交读的脏读问题,但是在事务 A当中查看到的事务B提交前后的内容发生变化,两次读的数据不一致了,这个问题叫做不可 重复读(也就事务A无法再读到事务B提交前的数据了)。
3.REPEATABLE(可重复度) 可重复读 终端1插入数据提交后,终端2提交后,才能看到插入后的数据 不存在脏读 幻读存在 不可重复读得到解决 AB
A
B查看
A
B
4. SERIALIZABLE(可串行读): 事务的最高隔离级别,它可以解决脏读、不可重复读、幻读的问题;但是设置这种隔离级别, mysql处理事务的性能会下降,它一般很少用,只用于对数据一致性要求特别高的事务当中; 事务A: mysql> SET SESSION TX_ISOLATION=‘SERIALIZABLE’; Query OK, 0 rows affected (0.00 sec)
mysql> BEGIN; Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM student2 WHERE id<7; ±—±------------+ | id | name | ±—±------------+ | 1 | zhaosi | | 2 | zhaowu | | 3 | zhaoliu | | 6 | zhaoxiaosan | ±—±------------+ 4 rows in set (0.00 sec)
事务B: mysql> SET SESSION TX_ISOLATION=‘SERIALIZABLE’; Query OK, 0 rows affected (0.00 sec)
mysql> BEGIN; Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO student2 VALUES(5,‘zhaolaoer’); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction //插入的id=5的数据,执行insert命令被阻塞了,过了超时时间之后返回错误信息; 原因是事务A对student的数据正在进行查询,student2表的相应字段被锁定,所以无法插入; 事务A提交了以后,事务B就可以正常插入数据了。
锁 读锁(共享锁,s锁) 如果事务a对于表s加了读锁,其他事务可以继续对s 加读锁,但是不能加写锁,保证数据可以被读取,但是不能写入 写锁(排他锁,x锁) 如果事务a 对于表s 加了写入锁,其他事务不能对s加任何锁,除非a释放了对于s的加锁,保证其他事务对于s既不能读也不能写
事务保存点(仅对事务有效) Savepoint 名字 对事务进行存档 读取保存点 Rollback to 保存点名字 回滚到指定位置的保存点 保存点只能存在于事务中,如果离开事务,保存点设置不成功,且保存点只能向前进行回滚,一旦回滚到之前的保存点,在其之后的保存点将会失效。