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