您的位置:首页 > 博客中心 > 数据库 >

MySQL事务概述

时间:2022-03-10 18:07

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3858050.html

 

 

 

1 事务(Transaction)概述

1.1 数据库事务的四个特性:ACID

原子性(Atomicity)

           \ 现象   

隔离级别  \

脏读取 不可重复读取 幻读 未提交读  允许 允许 允许 已提交读  不允许 允许 允许 可重复读  不允许 不允许 允许 可串行化  不允许 不允许 不允许

 

 

 

2 MySQL的事务

2.1 MySQL的事务处理命令

在命令行交互环境下,或存储过程中,可以使用如下命令方便的操作事务。

初始化事务

命令:START TRANSACTION;

 

事务回滚

命令:ROLLBACK;

 

提交事务

命令:COMMIT;

 

设置保存点

命令:SAVEPOINT identifer

 

删除事务的保存点

命令:RELEASE SAVEPOINT identifer

 

回滚至保存点

命令:ROLLBACK TO [SAVEPOINT] identifer

 

自动提交

在MySQL中,若不更改其自动提交变量,则系统会自动向数据库提交结果。

关闭自动提交:SET AUTOCOMMIT = 0;

关闭自动提交之后,只有使用COMMIT命令后,才会提交事务。

 

查看AUTOCOMMIT值:

命令:select @@autocommit;

 

或命令:show variables like ‘autocommit‘;

 

 

 

2.2 事务的实现

事务的隔离性由数据库的锁来实现。原子性,一致性,持久性由数据库的redo log和undo log来完成。

  • redo log称为重做日志,用于保证事务的原子性和持久性。
  • undo log用来保证事务的一致性。

 

 

2.3 MySQL的隔离级别

MySQL的默认事务隔离级别为Repeatable Read(可重复读)

MySQL中InnoDB存储引擎结合了MVCC和Next-Key Lock锁的算法,避免了幻读的产生。InnoDB存储引擎在默认的Repeatable Read的事务隔离级别下,已经能完全保证事务的隔离性要求。即达到了Serializable隔离级别。

查看当前数据库使用的隔离级别。global.tx_isolation变量表示全局事务。tx_isolation表示当前会话的事务。

命令:select @@global.tx_isolation , @@tx_isolation;

 

修改当前数据库使用的隔离级别,使用SET语句对tx_isolation变量进行设置。用户需要有SUPER权限,才可以执行进行隔离级别的修改。

基本命令格式:SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

 

在默认情况下,SET TRANSACTION会为下一个事务(还未开始)设置隔离等级。

若使用GLOBAL关键词,则语句会设置全局性的默认事务等级,用于从该点以后创建的所有新连接。原有的连接不受影响。

若使用SESSION可以设置默认事务等级,用于对当前连接的事务。

 

例:将当前会话的事务隔离级别设置为Read Uncommitted(未提交读)。

命令:SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

 

 

2.4 分布式事务

InnoDB存储引擎支持XA事务,通过XA事务实现分布式事务。使用分布式事务时,InnoDB存储引擎的隔离级别必须设置为SERIALIZABLE。

XA事务允许不同数据库的分布式事务,只要参与在全局事务中的每个节点都支持XA事务。Oracle,SQL Server都支持XA事务。

XA事务由一个或多个资源管理器、一个事务管理器以及一个应用程序组成。

  • 资源管理器:提供访问事务资源的方法。通常一个数据库就是一个资源管理器。
  • 事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器进行通信。
  • 应用程序:定义事务的边界。

 

 

2.5 事务与性能

很多应用其实是不需要事务的。例,在数据仓库中,若没有ETL这些操作,只是简单的报表查询是不需要事务的。

传统观点认为,事务隔离级别越高,数据越安全,但性能就越慢。事务隔离级别越低,性能就越快,但数据越不安全。

但在Jim Gray在《Transaction Processing》一书中指出,REPEATABLE READ 与SERIALIZABLE 的开销几乎是一样的。SERIALIZABLE 甚至可能更优。READ UNCOMMITTED的隔离级别也不会有太大的性能提升。

 

 

2.6 锁的简要介绍与使用

数据库锁也就是所谓的悲观锁。

 

2.6.1 锁的类型

读锁

又称共享锁、S锁。被锁定对象只允许被读,不允许被写。

若事务T对数据对象A加上读锁,则事务T可以读A但不能修改A,其他事务只能再对A加读锁,而不能加写锁,直到事务T释放A上的读锁。

写锁

又称排他锁、X锁。

若事务T对数据对象A加上写锁,事务T可以读A也可以修改A,其他事务不能读A,也不能再对A加任何锁,直到T释放A上的锁。

 

2.6.2 表级锁

操作对象是数据表,是系统开销最低但并发性最低的一个锁策略。

命令格式:LOCK TABLES 表1 锁类型, 表2 锁类型 ... ;

LOCK命令可以同时对多张表加锁。锁类型为READ、WRITE。

 

例:对student表添加读锁。

命令:lock tables student read;

 

例:对student表添加写锁。

命令:lock tables student write;

 

在用LOCK TABLES给表显式加表锁时,必须同时取得所有涉及到表的锁,并且MySQL不支持锁升级。也就是说,在执行LOCK TABLES后,只能访问显式加锁的这些表,不能访问未加锁的表;同时,如果加的是读锁,那么只能执行查询操作,而不能执行更新操作。其实,在自动加锁的情况下也基本如此,MyISAM总是一次获得SQL语句所需要的全部锁。这也正是MyISAM表不会出现死锁(Deadlock Free)的原因。

 

解锁

命令:UNLOCK TABLES;

UNLOCK命令会释放所有处于锁定状态的数据表。

 

 

2.6.3 行级锁

操作对象是数据表中的一行。行级锁对系统开销较大,处理高并发较好。

 

行级别的读锁

命令格式:SELECT ... LOCK IN SHARE MODE;

MySQL会对查询结果集中每行都添加共享锁。

 

行级别的写锁

命令格式:SELECT ... FOR UPDATE;

MySQL会对查询结果集中每行都添加排他锁,在事物操作中,任何对记录的更新与删除操作会自动加上排他锁。

 

 

2.6.4 死锁

多个资源的并发经常会发生死锁现象。

表级锁是不会产生死锁的。MyISAM使用表级锁模拟事务是安全的。

InnoDB引擎拥有自动检查死锁的功能。当发现死锁现象,会自动解决死锁问题。

 

 

2.6.5 MySQL伪事务

由于MyISAM存储引擎可以支持表锁(不支持行级锁)。可以使用表级锁模拟事务。这种模拟的事务侧重点在于操作的隔离。这不是真正的事务,不具备回滚的操作。

表级锁是不会产生死锁,可以安全使用。

 

 

 

2.7 MVCC

MVCC,Multiversion Currency Control,即多版本并发控制。

一般情况下,事务性储存引擎不是只使用表锁,行加锁的处理数据,而是结合了MVCC机制,以处理更多的并发问题。Mvcc处理高并发能力最强,但系统开销比最大(较表锁、行级锁),这是最求高并发付出的代价。

在Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都实现了三个隐藏字段:

6字节的事务ID(DB_TRX_ID )

7字节的回滚指针(DB_ROLL_PTR)

隐藏的ID

使用这三个字段,利用类似于乐观锁的机制实现了近似的MVCC机制。具体原理参看相关参考资料。

 

 

 

关于MVCC的一些参考资料:

http://coolshell.cn/articles/6790.html

http://www.jayxu.com/2012/03/13/13326/

http://jishu.zol.com.cn/2960.html

http://blog.csdn.net/chen77716/article/details/6742128

 

 

 

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3858050.html

MySQL事务概述,布布扣,bubuko.com

热门排行

今日推荐

热门手游