什么是事务?
所谓事务,就是指数据库中的一组操作,这些操作要么全部都执行成功,要么全部都执行失败,执行成功的事务提交到数据库中,执行失败的事务则回滚。
事务的四大特性
- 原子性(Atomicity)
原子是最小的单位,代表了不可分割。原子性表明,事务是数据库中操作的最小单元,事务中的操作要么全部成功,要么全部失败。 - 一致性(Consistency)
事务的执行前后,数据库的状态必须保持一致。 - 隔离性(Isolation)
一个事务的执行不能被另外的事务所干扰,事务执行的过程对于其他事务而言是隔离的。也就是说,另外的事务查看的数据,要么是一个事务提交前的数据,要么就是一个事务提交后的数据,事务执行的中间过程是隔离的。 - 持久性(Durability)
一个事务成功提交后,那么这个事务所做的操作引起的数据变化,会被持久化到数据库中。
数据库的读问题
事务的四大特性中,隔离性是保证事务安全的一个重要特性,如果不考虑事务的隔离性,就会引发数据库的读问题。
- 脏读:一个事务读到另一个事务未提交的数据。【解决方案:读已提交】
- 不可重复读:一个事务读到另一个事务已提交的update数据,导致一个事务前后两次读取的数据不一致。【解决方案:重复读】
- 幻读:一个事务读到另一个事务已提交的insert数据,导致一个事务中多次查询结果不一致。【解决方案:序列化读】
数据库的隔离级别
为了解决数据库的读问题,于是设立了数据的隔离级别。
- Read uncommitted:读未提交,任何读问题解决不了。
- Read committed:读已提交,这个事务的隔离级别,在事务开启时,要等另一个事务提交后才能读取数据,可以解决脏读问题,但是不可重复读和幻读有可能发生。
- Repeatableread:重复读,这个的隔离级别,在事务开启式,不允许其它事务进行update操作,可以解决脏读和不可重复读,但是幻读有可能发生。
- Serializable:序列化读,所有事务串行化顺序执行,解决所有读问题。不过这个事务的隔离级别会严重拖慢数据库性能。
Spring的事务管理
有了以上的事务知识,那么我们就可以来看一看Spring的事务管理了。
在Spring中,PlatformTransactionManager接口是事务平台管理器,是Spring中用于真正管理事务的对象,它有两个具体的实现类,底层分别使用不同的事务管理方式。
- DataSourceTransactionManager:底层使用JDBC管理事务
- HibernateTransactionManager:底层使用Hibernate管理事务
Spring一共定义了七种事务的传播行为
保证多个操作在同一个事务中
- PROPAGATION_REQUIRED:默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来。
- PROPAGATION_SUPPORTS:支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
- PROPAGATION_MANDATORY:如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
保证多个操作不在同一个事务中
- PROPAGATION_REQUIRES_NEW:如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
- PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理。
- PROPAGATION_NEVER :如果A中有事务,报异常。
嵌套式事务
- PROPAGATION_NESTED:嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。
Spring编程式事务管理(了解)
spring编程式事务管理,由于代码书写多,在正式开发中几乎不会使用,该知识点仅限于了解。
1 | <!-- 第一步:在spring的配置文件中配置事务管理器 --> |
1 |
|
Spring的声明式事务管理
基于xml配置文件的方式
1 | <!--spring提供的事务管理器,注入dataSource--> |
基于@Transactional注解方式
1 | <!--开启spring的基于注解的的事务管理--> |
1 |
|
基于@Transactional注解方式的事务管理,也可以通过注解中属性来定义事务管理的方式。
- rollbackFor :(值为异常的字节码对象)遇到该异常时回滚
- noRollbackFor:(值为异常的字节码对象)遇到该异常时不回滚
- propagation :(值为Propagation枚举对象)事务的传播行为
- readOnly:(值为true或者false)事务是否只读
Spring事务的回滚规则:在Spring的事务管理中,默认只有遇到运行时异常才会回滚事务,遇到编译期异常默认不回滚事务。
当然,开发者也可以通过自己指定遇到某种异常回滚或者不回滚。