理解数据库事务
2018年10月20日
事务是数据库提供的一种功能,为了保证数据操作的安全性。在数据库中,一个事务可以是一条语句,也可以是多条语句的联合。事务应该具有4个属性:原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性。
事务的隔离级别
- 读未提交 Read Uncommitted:一个事务可以读取另一个未提交的数据,容易出现脏读的情况。
- 读提交 Read Committed:一个事务等另外一个事务提交之后才可以读取数据,但会出现不可重复读的情况(多次读取的数据不一致),读取过程中出现UPDATE操作,会多。(大多数数据库默认级别是RC,比如SQL Server,Oracle),读取的时候不可以修改。
- 可重复读 Repeatable Read: 同一个事务里确保每次读取的时候,获得的是同样的数据,但不保障原始数据被其他事务更新(幻读),Mysql InnoDB 就是这个级别。
- 序列化 Serializable:所有事物串行处理(牺牲了效率)
脏读
如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
不可重复读
同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。不可重复读的重点是修改:同样的条件, 你读取过的数据, 再次读取出来发现值不一样了幻读:(针对其他提交前后,读取数据条数的对比)
幻读
同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。幻读的重点在于新增或者删除 (数据条数变化)同样的条件, 第1次和第2次读出来的记录数不一样事务的传播行为所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。
事务的传播行为
- REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
- REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于REQUIRED。