- 事务(transaction):事务指的是一组操作,里面包含了许多单一的逻辑,只要有一个逻辑没有执行成功,都算失败,所有的数据都会回归到最初的状态(回滚)。
- 事务的四大特性——ACID特性
- 原子性(Atomicity):一个事务中的所有操作要么全部成功,要么全部失败,不会结束在事务操作的中间阶段。
- 一致性(Consistency):事务在开始之前和事务结束以后,数据库的完整性没有被破坏。
- 隔离性(Isolation):数据库有允许多个并发事务同时对其数据进行读写和修改,隔离性可以保证多个事务并发执行时之前数据会不产生冲突或影响。
- 持久性(Durability):事务处理结束之后,对数据的修改是永久性的。
- 事务的安全隐患,在不考虑事务的隔离级别设置的情况下,会出现如下问题:
- 读问题,主要分为如下几种:
- 脏读:一个事务读取到了另外一个事务还未提交的数据。
- 不可重复读:一个事务读到了另外一个事务已提交的数据,造成了前后两次的查询结果不一致,主要指的是update和delete。
- 幻读:一个事物读到了另外一个事务还未提交的数据,造成了前后查询数据不一致问题,主要指的是insert的数据。
- 写问题:丢失更新,解决写问题的办法如下:
- 悲观锁(认为一定会出现丢失更新):可以在查询的时候加入for update — (for update 数据库锁机制:排他锁)
- 乐观锁(认为一定不会出现丢失更新):乐观锁需要程序员手动控制,手动加入时间戳或者version;如果有人做出修改,则改变version的值。事务B修改之前进行版本匹配,如果不一致,再重新查询。
# 悲观锁的查询SQL语句:
select * from account for update;
- 事务的隔离级别
- 读未提交(Read uncommitted):引发的问题是脏读问题
- 读已提交(Read committed):可以解决脏读问题,但是会引发不可重复读问题
- 可重复读(Repeatable read):可以解决脏读和不可重复读问题,但是会引发幻读问题(MySQL数据库默认为重复读)
- 串行化(Serializable):解决脏读、不可重复读、幻读问题(Oracle默认为可串行化)
- 事务在Java代码中的实现:
// 关闭事务自动提交
conn.setAutoCommit(false);
// 提交事务
conn.commit();
// 事务回滚
conn.rollback();
- 事务隔离级别按照效率划分,从高到低为:读未提交>读已提交>可重复读>可串行化