事务的传播属性
当一个事务方法被另一个事务方法调用时,应指定该事务如何传播,例如是在当前事务运行还是再开启一个事务运行
用注解 @Transactionl(propagation=*) 声明传播方式
七种传播属性
REQUIRED 如果有事务在运行,当前的方法就在这个事务内运行,否则就启动一个新的事务,并在自己的事务内运行
REQUIRED_NEW 当前方法必须启动事务,并在它自己的事务内运行,如果有事务正在运行,应该将他挂起
SUPPORTS 如果有事务在运行,当前的方法就在这个事务内运行,否则他可以不运行在事务中
NOT_SUPPORTE 当前的方法不应该运行在事务中,如果有运行的事务,将他挂起
MANDATORY 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVER 当前方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED 如果有事务在运行,当前的方法就应该在这个事物的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行
事务的四个属性——ACID
- 原子性(Atomicity)
将一个事务中的操作看作一个原子,具有不可分割性,要么全部成功,要么全部失败,中途失败要进行事务的回滚
- 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态,数据库的一致性是建立在原子性的基础之上的
- 隔离性(Isolation)
通常,数据库是由多用户并发访问,应为每个用户各自开启一个事务,对用户进行隔离保证相互之间无干扰。数据库定义了各种隔离级别,以在并发性和数据完整性中权衡
- 持久性(Durability)
事务完成后,对数据库的改变应是永久的,不会因为其他原因更改或丢失,即使是硬件问题,也应可以通过在日志中记录事务完成的任务进行重建
事务并发问题
- 脏读:一个事务读取另一个事务未提交的数据
- 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。这个事务在两次读取之间该数据被其它事务所修改
- 幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据
- 第1类丢失更新(回滚丢失):一个事务进行撤销回滚时,将另一事务的更新也撤销了
- 第2类丢失更新(覆盖丢失):一个事务更新覆盖另一事务的更新数据,造成另一事务所做的操作丢失
数据库锁机制
数据库通常会通过锁机制来解决数据并发访问问题,
按锁类型划分,可分为共享锁
、排他锁
按锁的粒度划分,可分为表级锁
、行级锁
、页级锁
按使用机制划分,可分为乐观锁
、悲观锁
直接使用锁非常麻烦,为此数据库为用户提供了自动锁机制,用户指定会话的事务隔离级别(稍后补上)
事务隔离级别
- Read Uncommited,读未提交,数据库最弱的隔离级别(完全不隔离),存在脏读、不可重复读、幻读的诸多问题
- Read Commited,读已提交,一个事务要等到另一个事务提交后才能读取数据;解决脏读问题;还可能会出现不可重复读、幻读
- Repeatable Read,可重复读,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务;解决脏读和不可重复读问题;还可能会出现幻读,Mysql默认级别
- Serializable,可序列化,最高的事务隔离级别,事务串行化顺序执行;避免脏读、不可重复读与幻读;但效率低,一般不用