事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。
定义:一件事从开始发生到结束的整个过程
作用:保持数据的一致性,保证呈批的SQL语句要么全部执行,要么全部不执行
事务必须满足四个条件(ACID)
原子性(Atomicity,或称不可分割性):一个事务中所有操作要么全部完成,要么全部不完成,不会结束在中间某个环节。事务执行过程中发生某个错误,会回滚(Rollback)到事务执行前状态,就像未发生一样。
一致性(Consistency):在事务开始之前和事务结束之后,数据库的完整性没有被破坏。表示写入数据必须满足所有预设规则,这包含资料的精确度,串联性以及后续数据库可以自发性的完成预定的工作。
隔离性(Isolation,又称独立性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行由于交叉执行而导致数据的不一致。事务隔离分为不同的等级,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性(Durability):事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失。
多个事务并发操作问题
多个事务同时访问数据库的时候,会发生以下5类问题。包括3类数据读(脏读,不可重复读,幻读),2类数据更新(第一类数据丢失,第二类数据覆盖更新)
1)脏读(dirty read):A事务读取B事务尚未提交的的更改数据,并在这个数据的基础上操作。如果B事务回滚,那么A事务读到的数据根本不是合法的,称为脏读。在oracle中,由于有version控制,不会出现脏读。
2)不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样。
3)幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据。
4)数据丢失:当两个或多个事务选择同一数据,并且基于最初选定的值更新该数据时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。
5)数据覆盖更新:A事务提交时,把已提交的B事务的数据覆盖掉。
三级封锁协议
1)一级封锁协议:事务T中如果对数据R有写操作,必须在这个事务中对R的第一次读操作前对它加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。 一级封锁协议可以防止丢失修改,并保证事务T是可恢复的。
2)二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后方可释放S锁。 二级封锁协议除防止了丢失修改,还可以进一步防止读“脏”数据。
3)三级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。 三级封锁协议除防止了丢失修改和不读“脏”数据外,还进一步防止了不可重复读。
事务隔离级别
三级封锁协议反映在实际的数据库系统上,就是四级事务隔离级别。四种事务隔离机制就是在逐渐的限制事务的自由度,以满足对不同并发控制程度的要求。以下就是数据库的四种隔离级别:
Read Uncommitted、Read Committed、Repeatable Read、Serializable
Mysql默认为Repeatable Read
mysql事务控制语句
begin或START TRANSACTION;显式地开启一个事务;
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改成为永久性的;
rollback : 有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier;把事务回滚到标记点;
set transaction :用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有Read Uncommitted、Read Committed、Repeatable Read、Serializable
Mysql事务处理的主要两种方法
1)用begin , commit , rollback 来实现
- MySQL中的sql命令会自动提交(commit)到数据库 show variables like "autocommit":
- begin; ..... 一条或多条SQL语句 ## 此时autocommit被禁用
- commit; | rollback ; (提交) (回滚) 【当输入commit 提交时数据提交到数据库并终止 当输入rollback 回滚时数据不提交到数据库并终止】
2)用set改变Mysql提交模式
- SET AUTOCOMMIT=0 禁止自动提交
- SET AUTOCOMMIT=1 开启自动提交