首先需要明确:MySQL支持几种基本的数据库引擎,有的引擎支持明确的事务处理管理,有的引擎不支持MyISAM不支持明确的事务处理管理,而InnoDB支持。
事务处理可以用来维护数据库的完整性,它保证成批的MySQL操作(好几条MySQL语句执行完再提交到数据库,这里大家可能有点不明白,其实我们在数据库中执行一条sql语句的时候,系统默认的在输入这条语句时执行begin,当我们写完这条sql语句,按下回车键,系统就会commit,进行提交。那么所谓事务,就是我们自己输入begin,然后执行一些sql语句之后,再自己执行commit提交到数据库,所以begin——commit之间的语句就是一个成批的MySQL操作)要么完全执行,要么完全不执行。
事务(transaction):一组SQL语句
回退(rollback):撤销指定SQL语句的过程
提交(commit):指将未存储的SQL语句结果写入数据库表
有些MySQL语句必须放在一起执行完之后再提交给数据库。
比如:银行转账的问题,从一个账号扣款并使另一个账号入账,这两个操作要么都执行,要么都不执行,所以将这样的情况看成一个事务。
一个事务必须被视为一个不可分割的最小工作单位,整个事物中的所有操作要么全部提交成功,要么全部失败回滚。
从一个一致性的状态转换到另外一个一致性的状态。比如:将id1银行卡中的钱转出,此时银行系统崩溃,那么并没有将钱转入到id2这个银行卡中,那么id1账户并不会损失钱财,因为这一个事物并没有提交,所以并不会修改数据库中的数据。
一个事物所做的修改在最终提交以前,对其他事物是不可见的。
即使没有commit,也会在其他会话窗口中还能查看当前数据库表中的数据。
一个事务开始时,当前会话窗口只能“看见”已经提交的事务所做的修改,也就是说当其他会话窗口执行了增删改查,即使当前会话窗口没有将事务commit,只要执行select 查询语句,就能看到其他会话窗口增删改查之后的数据。但是这个事务只有在已经commit之后,才能在其他会话窗口查看这个事务操作的数据库表中的数据。
当前会话窗口中正在执行一个事务,另外一个窗口执行了(比如增加操作),那么在当前会话窗口的事务中,执行select,所看到的数据表的信息不变,保证了同一事务中多次读取同样记录的结果是一致的。
示例:
查看当前会话隔离级别:
使用c215数据库,创建student1表。
插入三条数据之后显示当前表中数据如下:
会话窗口1开始一个事务,查看当前表的内容:
会话窗口2也在当前c215数据库中,然后并不开始事务(也就是不自己输入begin,因为自己输入begin和commit表示自己控制事务块),直接执行一条插入语句,如下:
然后在会话窗口1中的事务中,查看表的内容是否发生变化——结果是和之前数据一样,并没有会话窗口2的第四条语句。
隔离级别是可以进行更改的:
设置全局隔离级别
set global transaction isolation level REPEATABLE READ;
set global transaction isolation level READ COMMITTED;
set global transaction isolation level READ UNCOMMITTED;
set global transaction isolation level SERIALIZABLE;
设置会话隔离级别
set session transaction isolation level REPEATABLE READ;
set session transaction isolation level READ COMMITTED;
set session transaction isolation level READ UNCOMMITTED;
set session transaction isolation level SERIALIZABLE;
强制事务串行执行,也就是一个事务执行完才能执行下一个sql语句。
一旦事物提交,其所做的修改就会永久保存到数据库中。
当前事务执行了begin,并没有执行commit,那么在其他窗口进行该表的增删改查,在当前窗口读不到。但是在本窗口中可以读到,那么读到的数据因为没有提交到数据库,就会产生幻行,幻读。