Mysql学习笔记(6):事务

概念

TCL (Transaction Control Language) :事务控制语言

事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。

MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关,下面是两个常用引擎:

  • MyISAM:不支持事务,用于只读程序提高性能
  • InnoDB:支持ACID事务、行级锁、并发

事务的特性:ACID

  • 原子性(A):一个事务不可再分割,要么都执行要么都不执行
  • 一致性(C):一个事务执行会使数据从一个一致状态切换到另外一个一致状态(整体始终一致)
  • 隔离性(I):一个事务的执行不受其他事务的干扰
  • 持久性(D):一个事务一旦提交,则会永久的改变数据库的数据.


案例:转账
    张无忌  1000
    赵敏    1000

    update 表 set 张无忌的余额=500 where name='张无忌'
    发生意外,报错什么的
    update 表 set 赵敏的余额=1500 where name='赵敏'

    转账业务,张无忌给赵敏转账500。首先扣除张无忌的账户的钱,然后增加赵敏账户的钱。

    如果不使用事务中途发生了错误,结果是张无忌的钱少了,而赵敏的钱没增加。这就违背了一致性原则。


==========

事务操作

  • 查看服务器引擎:
SHOW ENGINES;
  • 查看自动提交参数设置:
SHOW VARIABLES LIKE 'autocommit';

MySQL默认操作模式就是autocommit自动提交模式。这就表示除非显式地开启一个事务,否则每个查询都被当做一个单独的事务自动执行。

  • 显示地开启一个事务:

START TRANSACTION;
  • 显示开启事务的操作是:
START TRANSACTION;  #开启一个事务
 update 表 set 张无忌的余额=500 where name='张无忌'
 update 表 set 赵敏的余额=1500 where name='赵敏'
COMMIT;  #提交事务

当autocommit开启时,如果不显示开启事务,这时候使用 COMMIT ROLLBACK 是不起作用的。

  • 设置autocommit关闭:
SET autocommit=0;
或者
SET autocommit=off;

自动提交关闭后,每次修改数据库后必须手动进行提交或回滚。

这种设置是会话(session)级别的,即每个连接都有各自的配置。

关闭了自动提交后,如果更新了数据库(CUD操作)就会自动开启一个事务,直到执行COMMIT或者ROLLBACK语句结束事务。

==========


事务的隔离级别

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

  • 脏读(Drity Read):某个事务已更新一份数据但是未提交,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
  • 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间另一个事务对数据进行了更新。
  • 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

数据库事务的隔离性:  数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题.

隔离级别:一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱.

数据库提供的4 种事务隔离级别:

1. Read Uncommitted(读取未提交)

  • 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。脏读、不可重复读和幻读都会出现。
  • 本隔离级别很少用于实际应用,因为会出现很多问题,而它的性能也不比其他级别好多少。


2.Read Committed(读取已提交)

  • 只允许事务读取已经被其他事务提交的变更,避免了脏读。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。
  • 这种隔离级别可能会出现不可重复读(Nonrepeatable Read)问题,因为可能会有其他事务在该事务处理其间可能会有新的commit,所以同一select可能返回不同结果。
  • 幻读(Phantom Read)也无法避免。
  • 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)


3. Repeatable Read(可重复读)

  • 可避免脏读和不可重复读问题
  • 无法避免幻读(Phantom Read)
  • InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制可解决幻读(Phantom Read)问题。
  • 这是MySQL的默认事务隔离级别,一般Mysql应用都会使用这个隔离级别。


4.Serializable(可串行化)

  • 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁,如果一个事务中使用到了某个表,就会将之锁住,其他的事务对于这个表的操作只能等待。在这个级别,可能导致大量的超时现象和锁竞争,开启事务后锁定表或者行,不让其他对象获取到,直到事务提交才释放锁。
  • 这种隔离级别可以避免上面所有的并发问题,但是性能十分低下。


----------

在Mysql中设置隔离级别

Oracle 支持的2 种事务隔离级别:READCOMMITED, SERIALIZABLE。

Oracle 默认的事务隔离级别为: READ COMMITED

Mysql 支持4 种事务隔离级别.Mysql 默认的事务隔离级别为: REPEATABLE READ

每启动一个mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量@@tx_isolation, 表示当前的事务隔离级别.

  • 查看当前连接的隔离级别:

SELECT @@tx_isolation;
#或者
select @@session.tx_isolation;
  • 设置当前会话隔离级别

set tx_isolation='repeatable-read'
#或者
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  • 查看系统当前隔离级别
select @@global.tx_isolation;
  • 设置系统当前隔离级别

    修改mysql.ini配置文件,在最后加上

#可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = REPEATABLE-READ






==========
select @@global.tx_isolation;

select @@global.tx_isolation;












  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值