一、事务的基本特征
1. 概念:如果一个包含多个步骤的业务操作,被事务管理,这些操作要么同时成功,要么同时失败。
事务执行是一个整体,所有的SQL语句都必须执行成功。如果其中有一条SQL语句出现异常,则所有的SQL语句都要回滚,整个业务执行失败。
2. 操作:
(1) 开启事务:start transaction
(2) 回滚:rollback
(3) 提交:commit
3.MySQL数据库中事务默认自动提交
事务提交的两种方式:
第一种方式:自动提交
MySQL就是自动提交的。
一条DML语句会自动提交一次事务。
第二种方式:手动提交
Oracle数据库默认是手动提交事务的。
需要先开启事务,在提交。
4.修改事务的默认提交方式:
查看事务的默认提交方式:
SQL语句:select @@autocommit;
结果:1代表自动提交;0代表手动提交
修改事务默认提交方式SQL语句为:set @@autocommit = 0;
这时写了DML语句,不写commit是不会生效的。
二、事务的四大特征(ACID)
原子性(Atomicity):事务是一个不可分割的最小单元,要么全部成功提交,要么全部失败回滚。失败回滚的事务,将不能对事物有任何影响。
一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
详解:
数据库状态如何变化?每一次数据变更就会导致数据库的状态迁移。如果数据库的初始状态是C0,第一次事务T1的提交就会导致系统生成一个SYSTEM CHANGE NUMBER(SCN),这时数据库状态由C0转变成C1。执行第二个事务T2的时候数据库状态由C1转变成C2,以此类推,执行第N个事务Tn的时候,数据库状态由C(n-1)变成Cn。
一致性可以从一致性读和一致性写两个方面来理解。
一致性读:事务读取数据只能从一个状态中读,不能从2个或2个以上状态读取。也就是说T(n)只能从C(n-1),C(n-2)...C1中的一个状态读取数据,不能一部分数据来自C(n-1),另一部分数据来自C(n-2)。
一致性写:事务执行的数据变更只能基于上一个一致的状态,且只能体现在一个状态中。T(n)的变更结果只能基于C(n-1),C(n-2)...C1状态,且只能体现在C(n)状态中。也就是说,一个状态只能有一个事务变更数据,不允许有2个或者2个以上事务在一个状态中变更数据。至于具体一致写基于哪个状态,需要判断T(n)事务是否和T(n-1),T(n-2),...T(1)有依赖关系。
隔离性(Isolation):隔离性是指当多个用户并发访问数据库时,比如同时访问一张表,数据库每一个用户开启的事务,不能被其它事务所做的操作干扰,多个并发事务之间,应当相互隔离。
例如同时有T1和T2两个并发事务,从T1角度来看,T2要不在T1执行之前就已经结束,要不在T1完成之后才开始。将多个事务隔离开,每个事务都不能访问到其它事务操作过程中的状态。
持久性(Durability):持久性是指事务的操作,一旦提交或回滚,对于数据库中数据的改变是永久的,即使数据库发生故障,也不能丢失已提交事务所完成的改变,数据库表的数据会持久更新。
三、事务的隔离级别
1.概念:多个事务之间应该是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置 不同的隔离级别就可以解决这些问题。
2.存在的问题:
脏读:一个事务,读取到另一个事务中没有提交的数据。
不可重复读(虚读):在同一个事务中,两次读取到的数据不一致。
幻读:一个事务操作(DML)数据表中的所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
3.隔离级别:
(1) Read Uncommitted 读未提交
产生的问题:脏读、不可重复读、幻读
(2) Read Committed 读已提交
产生的问题:不可重复读、幻读
(3) Repeatable Read 可重复读
产生的问题:幻读
(4) Serializable 串行化
可以解决所有问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低。既保证相对安全,又保证效率相对高。
4.SQL语句
(1) 数据库查询隔离级别
select @@tx_isolation
(2) 数据库设置隔离级别
set global transation isolation level 级别字符串; -- 把当前连接关掉,重新打开一个窗口,才会生效。