如果在事务的支持下,最终有两种结果:
事务的整个过程如原子操作一样,最终要么全部成功,或者全部失败,这个原子性是从最终结果上来看的,从最终结果上来看的话这个过程是不可分割的
一个事务必须使数据库从一个一致性转换到另一个一致性的状态
一致性:
一个事务的执行不能被其他事务干扰。事务与事务之间不能互相干扰。
一个事务一旦提交了,对数据库中的数据来说应该是永久性的。当事务提交之后,数据会持久化到磁盘中,修改时永久性的。
mysql中事务默认为隐式事务,执行insert,update,delete操作的时候,数据库会自动开启事务,提交或回滚事务
是否开始隐式事务时有变量autocommit控制的
隐式事务自动开启,提交或回滚,比如insert,update,delete语句,事务的开启,提交或回滚由mysql内部自动控制的
show variables like 'autocommit';
autocommit为ON表示开启自动提交
显式事务手动开启,提交和回滚,由开发者自动控制
语法:
//设置不自动提交事务
set autocommit = 0;
//执行事务的操作
commit;//提交事务
rollback;//回滚事务
示例1:
create table test( a int);
窗口1 | 窗口2 |
---|---|
设置为不自动提交(set autocommit= 0) | |
insert into test values (10) | |
select * from test;(有数据10) | select * from test;(没有数据10) |
commit; | |
select * from test;(有数据10) | select * from test;(有数据10) |
insert into test values (11) | |
select * from test;(有数据11) | select * from test;(没有11) |
rollback;(回滚) | |
select * from test;(没有数据11) | select * from test;(没有数据11) |
autocommit:还原
-- 自动提交事务
set autocommit = 1;
语法:
-- 开启事务
start transaction ;
-- 执行事务
-- 提交事务
commit ;
-- 回滚事务
rollback ;
案例1:
窗口1 | 窗口2 |
---|---|
show variables like ‘autocommit’;(默认开启) | show variables like ‘autocommit’;(默认开启) |
start transaction ;(开启事务) | |
insert into test values (11); | |
select * from test;(有数据) | select * from test;(没有数据) |
commit; | |
select * from test;(有数据) | select * from test;(有数据) |
案例2:
窗口1 | 窗口2 |
---|---|
show variables like ‘autocommit’;(默认开启) | show variables like ‘autocommit’;(默认开启) |
start transaction ;(开启事务) | |
delete from test where a = 11; | |
select * from test;(数据不存在11) | select * from test;(数据存在11) |
rollback;(回滚) | |
select * from test;(数据存在11) | select * from test;(数据存在11) |
示例:
窗口1 | 窗口2 |
---|---|
show variables like ‘autocommit’; | show variables like ‘autocommit’; |
start transaction ;(开启事务) | |
insert into test values (4); | |
savepoint insert_save1;(设置一个保存点insert_save1) | |
delete from test where a = 10; | |
savepoint delete_save2; | |
rollback to delete_save2; | |
commit; | |
select * from test;(有10数据) | select * from test;(有10数据) |
表示在事务中执行的是一些只读操作,比如查询,但不会做insert,update,delete操作,数据库内部对只读事务可能回有一个性能上的优化
用法:
start transaction read only ;
示例:
-- 提交事务
commit ;
-- 开启只读事务
start transaction read only ;
select * from test;
-- 删除全部数据
delete from test;
-- 只读状态无法删除数据
[25006][1792] Cannot execute statement in a READ ONLY transaction.
-- 提交事务
commit ;
select * from test;
只读事务中执行delete操作会报错: 只读状态无法删除数据
# 设置脏读
set session transaction isolation level read uncommitted;
脏读是指在数据库中,一个事务读取了另一个事务未提交的数据。
如果这些未提交的数据被回滚了,那么第一个事务读取的数据就是无效的。
set session transaction isolation level read committed ;
一个事务操作过程中可以读取到其他事务已提交的数据
事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(当前读)
一个事务操作中对应一个读取操作不管多少次,读到的数据结果始终都是一样的
幻读在可重复读的模式下才会出现的,其他隔离级别中不会出现
例如:
在可重复读模式下,如有用户表,手机号为主键,两个数据操作:
事务1:
start transaction read only ;
select * from user1 where iphone = 120;
insert into user1 values ('zhangsan',110);
commit ;
事务2:
对于事务2操作来说,发生幻觉了一样,
start transaction ;
insert into user1 values ('zhangsan',120);
select * from user1 where iphone = 120;
commit ;
事务中后面的操作(插入电话号码数据)需要提交事务之后才可以支持,对于事务2来说可以添加数据,但是不能查询数据,