一、什么是事务
1.概念
事务(Transaction):一个最小的不可再分的工作单元,一个事务对应一个完整的业务,一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成,事务只针对DML语句。
数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位,事务由事务开始与事务结束之间执行的全部数据库操作组成。
- mysql中,只有Innodb是支持事务
mysql> show engines;
# 查看Mysql的所有执行引擎可以到,默认的执行引擎是innoDB 支持事务,行级锁定和外键。
2.举例
以银行转账为例,账户转账是一个完整的业务,最小的单元,不可再分——也就是说银行账户转账是一个事务:
update account set money = money - 200 where id = 1;
update account set money = money + 200 where id = 2;
分析:
- 以上两个DML语句必须同时成功或者同时失败
- 最小单元不可再分,当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下,这个记录是在内存中完成的
- 当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步
- 若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务
3.数据库事务处理原则
- 保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式
- 当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来
- 要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。
- 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态
二、*事务的特性(ACID)
1.原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生,保证事务的整体性。
例:zhangsan给lisi转帐200元钱的时候只执行了扣款语句,就提交了,此时如果突然断电,zhangsan账号已经发生了扣款,lisi账号却没收到加款,在生活中就会引起纠纷。这种情况就需要事务的原子性来保证事务要么都执行,要么就都不执行。
2.一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
分析:
- 在事务开始前,数据库中存储的数据处于一致状态
- 在正在进行的事务中,数据可能处于不一致的状态
- 当事务成功完成时,数据必须再次回到一致状态
例:对银行转帐事务,不管事务成功还是失败,应该保证事务结束后表中zhangsan和lisi的存款总额跟事务执行前一致,如:zhangsan的账户有1000元,lisi的账户有1000元,现在zhangsan转账200元给lisi,不管事务成功还是失败,转账前后zhangsan和lisi的存款总额都应该是2000元。
3.隔离性(Isolation)
隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离,每个事务都有各自的完整数据空间。
4.持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
三、MySQL使用事务
1.MySQL的事务操作
(1)开启事务
- 任何一条DML语句(insert、update、delete)执行,标志事务的开启
- 命令:begin 或 start transaction
(2)提交事务
- 成功的结束,将所有的DML语句操作历史记录和底层硬盘数据来一次同步
- 命令:commit
(3)回滚事务
- 失败的结束,将所有的DML语句操作历史记录全部清空
- 命令:rollback
2.使用事务的方法
3.分析
开始事务:begin 或 start transaction ,注意:mysql5.5以上的版本,不需要手工书写begin,只要你执行的是一个DML,会自动在前面加一个begin命令,此方法又称为显示开启事务。
MySQL中用 autocommit参数设置事务是否自动提交
4.自动提交策略
MySQL默认已经开启自动提交,可以通过对应的设置来开启或者关闭自动提交。
- 查看自动提交设置
mysql> select @@autocommit; # @@用于查看全局变量
mysql> show variables like 'autocommit';
- 设置自动提交
mysql> set autocommit=0; # 针对当前连接会话
mysql> set global autocommit=0; # 针对全局事务
# 可以在C:\ProgramData\MySQL\MySQL Server
8.0\my.ini配置文件中增加一行
autocommit=0
注意:一般在有事务需求的MySQL中,将其关闭,使用begin手动开启,所以不管有没有事务需求,都建议设置为0,可以很大程度上提高数据库性能
5.设置回滚点
作用:可以创建一个或多个回滚点,将事务回滚到标记点,可以设置多个回滚点,格式:
savepoint 回滚点名
rollback to 回滚点
# 注意:手动设置回滚点,需要关闭事务自动提交,若自动提
交已开启,则语句执行后代表事务已提交,所有回滚点都会删
除,此时执行手动回滚会报错,即:
ERROR 1305 (42000): SAVEPOINT ** does not exist
6.事务的隐式提交
(1)概念
因为某些特殊的语句而导致事务自动提交的情况称为隐式提交。
(2)哪些事务不会自动提交?
- 使用start transaction开启事务
- 使用begin开启事务
- 把系统变量autocommit的值设置为OFF | 0
(3)常见的隐式提交
(4)注意
- 在MySQL中,为了避免隐式提交造成的隐患,建议使用显式提交操作,即通过手动执行COMMIT或ROLLBACK来明确事务的完成或回滚
- sql查询操作会在事务的上下文中执行,但是它并没有对数据进行写的操作,所以事务不会持有任何锁,在查询结束后会立即提交,因此,InnoDB所有的操作都是在事务中进行的