1.什么是事务:
事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.
2.事务特性(ACID)(4种):
原子性 (atomicity):强调事务的不可分割.事务包含的所有操作要么全部成功,要么全部失败回滚(使用 undo log ,从而达到回滚)
一致性 (consistency):事务的执行的前后数据的完整性保持一致.(通过回滚,以及恢复,和在并发环境下的隔离做到一致性)
隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰(使用锁以及MVCC,运用的优化思想有读写分离,读读并行,读写并行)
持久性(durability) :事务一旦结束,数据就持久到数据库(使用 redo log,从而达到故障后恢复)
3.如果不考虑隔离性引发安全性问题:
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的数据导致第一个事务对同一条数据多次查询结果不一致.(例如:A事务查看id=1的数据年龄显示为18,在A事务还没结束的时候,创建了事务B对id=1的数据进行修改年龄改为20,并进行了提交,然后事务A逻辑处理中又需要再次查询id=1的数据,发现年龄变成了20 ,这样的情况称为不可重复读)
幻读 :一个事务读到了另一个事务已经提交的数据,导致一个事务多次查询结果不一致.(例如:当事务A读取id>5的数据时有10条,在A事务还没有提交的时候,创建了另一个事务B新增了一条数据,当事务A再读取该id>5范围的数据行时,发现数据多了一条,这种情况称为幻读)
幻读和不可重复读的区别:
不可重复读: 重点是update数据。
幻读:重点是insert或delete数据。
4.解决读问题: 设置事务隔离级别(5种)
DEFAULT 使用底层数据库的默认隔离级别对于大多数的数据库来说,默认的隔离级别都是read commited
读未提交(read uncommited) :脏读,不可重复读,幻读都有可能发生
读已提交 (read commited):避免脏读。但是不可重复读和幻读有可能发生
可重复读 (repeatable read) :避免脏读和不可重复读.但是幻读有可能发生.
串行化的 (serializable) :避免以上所有读问题.最严格的事务隔离级别,要求所有事务被串行执行,不能并发执行,可避免脏读、不可重复读、幻读情况的发生。
事务的隔离级别要得到底层数据库引擎的支持, 而不是应用程序或者框架的支持.
Oracle 支持的 2 种事务隔离级别:READ_COMMITED , SERIALIZABLE
MySQL 支持 4 中事务隔离级别
5.事务的传播行为
- 保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
- 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
6.注解@Transactional说明
-
value :主要用来指定不同的事务管理器;
主要用来满足在同一个系统中,存在不同的事务管理器。
比如在Spring中,声明了两种事务管理器txManager1, txManager2.然后,
用户可以根据这个参数来根据需要指定特定的txManager. -
value 适用场景:在一个系统中,需要访问多个数据源或者多个数据库,
则必然会配置多个事务管理器的 -
REQUIRED_NEW:内部的事务独立运行,在各自的作用域中,可以独立的回滚或者提交;
而外部的事务将不受内部事务的回滚状态影响。 -
ESTED 的事务,基于单一的事务来管理,提供了多个保存点。
这种多个保存点的机制允许内部事务的变更触发外部事务的回滚。
而外部事务在混滚之后,仍能继续进行事务处理,即使部分操作已经被混滚。
由于这个设置基于 JDBC 的保存点,所以只能工作在 JDB C的机制。 -
rollbackFor:让受检查异常回滚;即让本来不应该回滚的进行回滚操作。
-
noRollbackFor:忽略非检查异常;即让本来应该回滚的不进行回滚操作。