咱们在开发时,会对数据进行持久化操做,如存入数据库中。当咱们操做数据库中的数据,后续可能会发生错误,抛出异常,前面对数据库的操做就会不可靠,在这种状况下须要回滚。spring
事务的做用就是保证在事务中每一步操做都是可靠的,每一步操做均可以成功执行,中途出现错误或异常都要还原到事务开始前的状态。数据库
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别能够逐个解决脏读、不可重复读、幻读这几类问题。数组
名词解释:并发
脏读(Drity Read):某个事务已更新一份数据,另外一个事务在此时读取了同一份数据,因为某些缘由,前一个RollBack了操做,则后一个事务所读取的数据就会是不正确的。性能
不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这多是两次查询过程当中间插入了一个事务更新的原有的数据。this
spring 中的实现:spa
public enum Isolation { // 底层数据库默认的隔离等级 DEFAULT(-1), // 一个事务能够读取另外一个事务修改但尚未提交的数据。 READ_UNCOMMITTED(1), // 该隔离级别表示一个事务只能读取另外一个事务已经提交的数据。 READ_COMMITTED(2), // 该隔离级别表示一个事务在整个过程当中能够屡次重复执行某个查询,而且每次返回的记录都相同。即便在屡次查询之间有新增的数据知足该查询,这些新增的记录也会被忽略。 REPEATABLE_READ(4), // 全部的事务依次逐个执行,这样事务之间就彻底不可能产生干扰,也就是说,该级别能够防止脏读、不可重复读以及幻读。 SERIALIZABLE(8); private final int value; private Isolation(int value) { this.value = value; } public int value() { return this.value; } }
2.2.1 PROPAGATION_REQUIRED:若是当前没有事务,就建立一个新事务,若是当前存在事务,就加入该事务,该设置是最经常使用的设置。代理
2.2.2 PROPAGATION_SUPPORTS:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就以非事务执行。code
2.2.3 PROPAGATION_MANDATORY:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就抛出异常。对象
2.2.4 PROPAGATION_REQUIRES_NEW:建立新事务,不管当前存不存在事务,都建立新事务。
2.2.5 PROPAGATION_NOT_SUPPORTED:以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
2.2.6 PROPAGATION_NEVER:以非事务方式执行,若是当前存在事务,则抛出异常。
2.2.7 PROPAGATION_NESTED:若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与PROPAGATION_REQUIRED相似的操做。
spring的实现:
public enum Propagation { // 若是当前存在事务,则加入该事务;若是当前没有事务,则建立一个新的事务。 // @Transactional 注解默认采用这个方案 REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), // 若是当前存在事务,则加入该事务;若是当前没有事务,则以非事务的方式继续运行。 SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), // 若是当前存在事务,则加入该事务;若是当前没有事务,则抛出异常。 MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), // 建立一个新的事务,若是当前存在事务,则把当前事务挂起。 REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), // 以非事务方式运行,若是当前存在事务,则把当前事务挂起。 NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), // 以非事务方式运行,若是当前存在事务,则抛出异常。 NEVER(TransactionDefinition.PROPAGATION_NEVER), // 若是当前存在事务,则建立一个事务做为当前事务的嵌套事务来运行;若是当前没有事务,则该取值等价于REQUIRED // 并不是全部的TransactionManager都能支持这个传播级别 NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; } }
@Transactional注解中经常使用参数说明
参数名称 |
功能描述 |
readOnly |
该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true) |
rollbackFor |
该属性用于设置须要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如: 指定单一异常类:@Transactional(rollbackFor=RuntimeException.class) 指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class}) |
rollbackForClassName |
该属性用于设置须要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如: 指定单一异常类名称:@Transactional(rollbackForClassName="RuntimeException") 指定多个异常类名称:@Transactional(rollbackForClassName={"RuntimeException","Exception"}) |
noRollbackFor |
该属性用于设置不须要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如: 指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class) 指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class}) |
noRollbackForClassName |
该属性用于设置不须要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如: 指定单一异常类名称:@Transactional(noRollbackForClassName="RuntimeException") 指定多个异常类名称: @Transactional(noRollbackForClassName={"RuntimeException","Exception"}) |
propagation |
该属性用于设置事务的传播行为,具体取值可参考表6-7。 例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) |
isolation |
该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的状况,一般使用数据库的默认隔离级别便可,基本不须要进行设置 |
timeout |
该属性用于设置事务的超时秒数,默认值为-1表示永不超时 |
@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚 public void methodName() { throw new Exception("注释"); } @Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new RuntimeException("注释");)会回滚 public ItimDaoImpl getItemDaoImpl() { throw new RuntimeException("注释"); }