事务简介
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,也就是说这些操作要么都成功,要么都失败
默认MySQL的事务时自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
事务操作
方式一:设置当前会话必须commit才提交到数据库
通过设置 @@autocommit = 0; 设置事务手动提交
设置完后,当前会话的sql语句执行但是不会提交到数据库,需要通过commit提交,也可以通过rollback回滚
方式二:开启事务
使用start开启事务
commit、rollback
事务四大特性(ACID)
- 原子性:同一个事务为原子性操作,要么都成功,要么都失败
- 一致性:在事务提交完成后,要保证数据的一致性。(比如转账该+1000的+1000,该-1000的-1000,总金额不变)
- 隔离性:在并发环境下,事务与事务之间应该做到相互不受影响
- 持久性:事务完成提交或者回滚之后,对于数据库中数据改变是永久的
并发事务问题
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一个数据库进行行操作)。并发虽然是必须的,但可能会导致以下问题。
- 脏读:一个事务读到另外一个事务还没有提交的数据。当一个事务正在访问数据并且对数据进行修改,而这种修改还没提交到数据库,这是另外一个事务也访问了这个数据,然后使用了这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。事务1读取到表中A = 100,修改 A = 200,但这次修改不一定成功(rollback),或者后续可能要再次修改A = 300,而事务2就读到了 A = 200,可能引起事务2后续操作错误
- 丢失数据:例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
- 不可重复读:一个事务同时读到一条记录,但是两次读到的数据不同,称为不可重复读。事务1第一次查询A = 100, 事务2将 A 修改成 200,事务1再次读取时 A = 200,和第一次读取到的不一样???
- 幻读:一个事务按照条件查询数据时,没有数据行,但是在插入数据时,又发现这个数据已存在,好像出现了“幻影”。T1查询几条数据,T2进行插入或者删除操作,T1再次进行读取发现多了一些数据,或者原来查到的一些数据不见了
事务隔离级别
select @@transaction_isolation;
但是MySQL在REPEATABLE-READ (可重复读) 事务中使用了Next-Key Lock(内隙+行锁)锁算法,可以避免幻读问题。InnoDB 存储引擎在 分布式事务的情况下一般会用到可串行化。