数据库 事务

Mysql事务的概念

事务是一种机制,一个操作序列包含了一组数据库的操作命令,所有命令都是一个整体,向系统提交或是撤销的操作,要么都执行,要么都不执行,它是一个不可分割的单位。

事务的特性

                     ACID:四个特性
1. A:原子性 最小单位,事务里的所有条件都是一个整体,不可分割,要么都成功,要么都失败
2. C:一致性

事务开始之前和事务结束之后,数据库的完整性约束没有被破坏,事务完成时,数据必须属于一至状态。

1.事务开始前,数据库中的存储数据要处于一致状态

2.进行中的事务,数据可能处于不一致状态

3.在事务最终完成时,必须再次回到已知的一致状态

3. I:隔离性 只在并发环境中,当不同事务同时操作相同数据时,每个事物都有各自完整的数据空间,对数据修改的所有的并发事务是彼此隔离的,表名事务必须是独立的,修改数据的事务可以在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同的事务结束之后访问这些数据
4. D:持久性 数据一旦提交,事务的效果将会被永久的保留在数据库中,而且不会被回滚。

事务总结

在事务管理中,原子性是基础,隔离性是手段,一致性是目的,持久性是最终结果

事务隔离性的隔离级别

                     mysql支持四种隔离级别
未提交读

                         read uncommitted  (RU)

允许脏读,允许一个事务可以看到其他事物未提交的修改

提交读

                         read committed    (RC)

只能看到已经提交的修改,未提交的修改是不可见的,可以防止脏读。orcale(神域:甲骨文)使用的就是提交读,sqlsever 也是用的提交读

可重复读

                             repeatable read  (RR)        

                       mysql的默认隔离级别

确保如果在一个事务中执行相同的select语句时,都能得到相同的结果,不管其他事物是否提交修改,可以防止脏读,以及不可重复读

串行读

                               serializable

也就是锁表,完全串行化(一个一个来,如果有人在查,那么其他任何人不能再操作),每一个事务都隔离,读写之间都会阻塞

事务隔离级别的作用范围

全局级 对所有的会话都有效
会话级 只对当前的会话有效

事务之间互相影响

脏读,不可重复读,幻读,丢失更新

当多个客户端并发的访问同一个表时,可能出现以下的一致性问题。
脏读

一方提交申请,但没有确认,另一方却可以看到未确认提交的修改。

脏读是不被允许的

不可重复读 一个事务内,多次读同一数据,前一个事务还没结束,另一个事务也访问该数据,在同一个事务之内,两次查询到的结果不一致,读不到相同的数据。
幻读 一个事务对一个表中的数据进行了修改,可能会涉及到表中的全部数据,另一个事务也修改了这个表中的数据,插入了一行新的数据,前一个事务会发现表中还有数据没有修改,类似于幻觉
丢失更新 即两个事务同时修改一条记录,a先修改了记录,b也修改了记录,b一旦提交,就会覆盖a的结果。

如何避免不一致性问题

1 对权限进行控制
2 根据情况来使用隔离级别,生产环境中最好是提交读,提交之后再读,测试环境就无所谓
3 生产环境只能允许一个人对一个事务进行操作,其他人不允许操作

查询当前隔离级别

查询全局事务的隔离级别

第一种查询方式
show global variables like '%isolation';

第二种查询方式
select @@global.tx_isolation;



查询当前会话事务的隔离级别

第一种方式
show session variables like '%isolation';

第二种方式
select @@session.tx_isolation;

如何设置全局事务的隔离级别

未提交读:read uncommitted

修改全局事务隔离级别
set global transaction isolation level read uncommitted;
#设置全局隔离级别为 未提交读 , 未提交读:read uncommitted

set @@global.tx_isolation='read uncommitted';
#临时设置隔离级别为 未提交读  , 一旦重启服务即失效,一般mysql不会重启



修改当前打开的会话事务隔离级别
set session transaction isolation level read uncommitted;
#全局设置

set @@session .tx_isolation='read uncommitted';
#临时设置


flush privieges;
#设置完毕后最好刷新一下


set global transaction isolation level repeatable read;
#设置全局为可重复读,mysql默认的隔离级别

set global TRANSACTION ISOLATION level Repeatable Read;

 事务控制语句

begin 或 start  , transaction
#开启一个事务

commit 或 commit work
#提交事务,并使已对数据库进行的所有修改变为永久性的

rollback 或 rollback work
#回滚结束会结束用户的事务,并撤销正在进行的所有的未提交的修改

savepoint s1 
#使用 savepoint 允许在事务中创建一个回滚点(存档),一个事务可以有多个savepoint , 如:savepoint s1/s2/s3

rollback to [savepoint] s1
#把事务回滚到标记点


#设置回滚示例
begin;
#建立事务

savepoint s1;
#建立回滚点

update  test set money=money-50 where id =2;
#更新 test  指定  money那一列 减 50 指定列名为id那一列 为2

rollback s1
#回滚到s1

使用set设置控制事务

set autocommit=0;      #禁止自动提交事务(仅针对当前会话)
set autocommit=1;      #开启自动提交(仅针对当前会话,mysql默认为1)

set global autocommit=0;    #禁止自动提交(针对全局事务)

set global autocommit=1;    #开启自动提交(针对全局事务,mysql默认为1)


show variables like 'autocommit';    #查看当前会话的autocommit值

show global variables like 'autocommit';   #查看全局事务的autocommit值 


如果没有开启自动提交,当前会话连接的mysql的所有操作都会当成一个事务直到你输入 rollback; 或 commit; 当前事务才算结束,当前事务结束前,新的mysql连接时无法读取到任何当前会话的操作结果。

如果开启了自动提交,mysql 会把每个sql语句(命令)当成一个事务,然后自动commit;(提交事务)

无论开启与否, begin;  commit;  rollback;  都是独立的事务

你可能感兴趣的:(数据库)