事务就是保证一组数据库操做,要么所有成功,要么所有失败。
MySQL 中事务支持都是在引擎层实现的
MySQL 是一个支持多引擎的系统,但并非全部的引擎都支持事务数据库
隔离级别出现的缘由是,当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了 “隔离级别” 的概念。不一样隔离级别数据库行为有所不一样。并发
隔离级别越高,效率就越低。不少时候要在两者之间找一个平衡点。
隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable)ide
读未提交:一个事务还没提交时,它作的变动就能被别的事务看到
读提交:一个事务提交以后,它作的变动才会被其余事务看到
可重复读:一个事务执行过程当中看到的数据,老是跟这个事务在启动的时候看到的数据是一致的。固然在可重复读隔离级别下,未提交变动对其余事务也是不可见。
串行化:顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。线程
实例说明:各隔离级别日志
各隔离级别的实现,数据库里会建立一个视图,访问的时候以视图的逻辑为准。
“可重复读” 隔离级别下,这个视图是在事务启动时建立,整个事务存在期间都用这个视图。
在“读提交” 隔离级别下,这个视图是在每一个 SQL 语句开始执行的时候建立的。
“读未提交” 隔离级别下直接返回记录上的最新值,没有视图概念。
“串行化” 隔离级别下直接用加锁的方式来避免并行访问。orm
隔离级别的配置方式是,transaction-isolation ,能够用 show variables 查看当前值。事务
事务隔离的实现it
在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操做。记录上的最新值,经过回滚操做,均可以获得前一个状态的值。io
不一样时刻启动的事务会有不一样的 read-view,同一条记录在系统中能够存在多的版本,就是数据库的多版本并发控制(MVCC)。
要获得那个 read-view 的值就必须将当前值依次执行全部的回滚操做获得innodb
当没有事务在须要用到这些回滚日志时,回滚日志会被删除。
当系统里没有比这个回滚日志更早的 read-view 的时候,就会删除这个回滚日志。
尽可能不要使用长事务,长事务意味着系统里面会有很老的事务视图,会占用大量的存储空间。
事务的启动方式
1,显示启动事务语句,begin 或 start transaction。配套的提交语句是 commit ,回滚语句是 rollback 。
2,setautocommit=0 , 这个命令会将这个线程的自动提交关掉。意味着若是你只执行一个 select 语句,这个事务就启动了,并且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开链接。
能够用 information_schema 库的 innodb_trx 这个表中查询长事务。好比下面这个语句查询持续时间超过 60s 的事务select * from information_schema.innodb_trx where TIME_TO_SEC(timediFF(now(),trx_started))>60