事务
事务由单独单元的一个或多个sql语句组成,在此单元中,每个mysql语句是相互依赖的。
如果单元中某条语句一旦执行失败或产生错误,整个单元回滚。受影响数据返回到事务开始之前的状态。如果单元中所有sql语句执行成功,事务顺利执行。
ACID属性
-
原子性
事务是一个不可分割的工作单位,事务中的操作要么都发生要么都不发生。
-
一致性
事务必须使数据库从一个一致性状态变换到另一个一致性状态。
-
隔离性
一个事务的执行不能被其他事务干扰,一个事务的内部操作和使用的数据对并发的其他事务是隔离的。
-
持久性
一个事务一旦被提交,接下来的其他操作和数据库故障都不应该对其有任何影响。
创建事务
-
隐式事务:事务没有明显的开启结束标记
如insert update delete
-
显式事务:事务有明显的开启结束标记
必须先设置自动提交功能为禁用
Set autocommit = 0;
语法
Set autocommit = 0;
【Start transaction;】
Sql语句。。。
Savepoint 节点名;
Commit;/rollback;
回滚点Savepoint
使用
Savepoint 节点名;
Rollback to 节点名;
SET autocommit = 0;
START TRANSACTION;
DELETE FROM authorss WHERE age = 20;
SAVEPOINT a;
DELETE FROM authorss WHERE age = 23;
ROLLBACK TO a ;
Delete 和 truncate 在回滚时的区别
SET autocommit = 0;
START TRANSACTION;
DELETE FROM book;
ROLLBACK ;
SET autocommit = 0;
START TRANSACTION;
TRUNCATE TABLE book;
ROLLBACK ;
truncate 仍然会删除,delete不会
事务并发问题
如果同时运行多个事务,当这些事务访问数据库中相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。
- 脏读
对于事务t1,t2,t1读取了已经被t2更新但还没有提交的字段。之后,如果t2回滚,t1读取的内容就是无效的。
t1修改name 为 a ,此时t2查询的name为a,
t1回滚,t2查询数据与之前不同。
- 不可重复读
对于t1,t2,t1读取了一个字段,之后t2更新该字段,t1再次读取该字段,值不同
t2先查询,t1修改并提交,t2再查询,数值不一样了。
- 幻读
对于两个事务t1,t2,t1读取了一个字段,t2新插入一些数据,t1再次读取同一张表,数据就会多出几行。
事务的隔离级别
- Read uncommitted(读未提交数据):会出现脏读,不可重复读,幻读。
- Read commit(读已提交数据):出现不可重复读和幻读
- Repeatable read (可重复读):出现幻读
- Serializable(串行化):都不会出现,但性能低下
Oracle 支持2种read commit serializable 默认Read commit
mysql支持4种,默认Repeatable read
查看事务的隔离级别
Select @@tx_isolation ;
修改事务的隔离级别
Set session transaction isolation level 隔离级别;