Spring事务

2019-09-26  本文已影响0人  少年丶要淡定

        今天我们去看一下spring是怎么管理事务的。我们先去了解一下事务的特性和spring事务的属性。spring并不是直接去管理事务,而是为JDBC、Hibernate等平台提供了一个模板接口来实现他们各自的事务管理器,我们去看一下:

事务管理器

        先去看看事务的特性,这些东西都老生常谈了(ACID),这里再提一下吧:

        原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

        一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

        隔离性(Isolation):隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

        持久性(Durability):持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

        我们再来看看spring事务都有什么属性:

        下边我们分别看一下属性具体是指什么,首先是事务的传播特性

spring事务的属性

        传播特性

        传播特性主要有七种,看一下:

        1、PROPAGATION_REQUIRED:当前方法必须运行在事务中,如果事务存在,则运行在这个事务中,事务不存在就重新开启一个事务。(支持事务)

        2、PROPAGATION_SUPPORTS:表示事务不是必须的,如果存在事务,则在事务中运行;如果不存在事务,就以非事务的方式运行。(支持事务)

        3、PROPAGATION_MANDATORY:表示方法必须在事务中运行,否则抛异常。(支持事务)

        4、PROPAGATION_REQUIRES_NEW:表示了事务的独立性。就是每个方法都拥有自己的事务,如果有事务存在,则将原事务挂起,重新开启一个新的事务。

        5、PROPAGATION_NOT_SUPPORTED:表示方法不在事务中运行,如果有事务存在,则挂起事务执行方法。(不支持事务)

        6、PROPAGATION_NEVER:不能存在事务。如果有事务存在,就抛异常。(不支持事务)

        7、PROPAGATION_NESTED:表示嵌套事务。如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点,叫save point,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行。那么问题来了,如果子事务回滚,父事务会回滚到之前建立的回滚点(save point);父事务回滚,子事务也会跟着回滚。(讲道理这个地方真的像极了生活中的父子关系,儿子犯错了,父亲也有责任;父亲犯错了,儿子也会收到影响)

        隔离级别

        隔离级别主要有三种,分别是:脏读、幻读、不可重复读。先看看这三种隔离级别都是表示什么

        脏读:一个事务读到另一个事务未提交的更新数据,所谓脏读,就是指事务A读到了事务B还没有提交的数据。

        幻读:幻读主要是发生在新增和删除的情景中。比如第一个事务执行修改操作,这个时候第二个事务进行新增或删除操作,导致第一个事务的结果有数据未修改或者缺少数据,这种现象被称作是幻读。

        不可重复读:事务读取了两次数据,在这两次的读取过程中另一个事务修改了数据,导致第一个事务的这两次读取出来的数据不一样。这种现象被称作是不可重复读。

        我们再看一下spring事务的隔离级别,它这里支持五种,我们分别看一下:

        1、ISOLATION_DEFAULT:这里就是选择数据库本身的隔离级别。Mysql的默认隔离级别是可重复读(ISOLATION_REPEATABLE_READ),Oracle的默认隔离级别是读已提交(ISOLATION_READ_COMMITTED)。

        2、ISOLATION_READ_UNCOMMITTED:读未提交。就是脏读。

        3、ISOLATION_READ_COMMITTED:读已提交。可以避免脏读。

        4、ISOLATION_REPEATABLE_READ:可重复读。避免了可重复读,但是还会有幻读的风险。

        5、ISOLATION_SERIALIZABLE:可串行化。最高级别的隔离级别,成功避免了脏读、幻读和不可重复读。就好像是串联电路一样,只能够逐一挨个执行,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务。

        超时

        所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。 默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

        只读

        事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、 JMS 资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在 TransactionDefinition 中以 boolean 类型来表示该事务是否只读。

        提到了spring事务,就难免涉及到Transactional这个注解,先看看注解都有什么重要的属性:

@Transactional

        看一下是怎么用的,然后讲讲都是什么意思:

@Transactional使用

        说一下这些属性:

        value:这个属性是指定事务管理器的,没人把它会放注解上,这个基本上不用。

        propagation:这里指的是spring事务的传播特性,对应上边的七种,默认是REQUIRED。

        isolation:隔离级别,对应上边的五种隔离级别,默认值是DEFAULT。

        timeout:用于设置事务的超时秒数,默认值为-1表示永不超时。

        readOnly:该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。从这这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在我们事务提交之后提交的数据)。

        rollbackFor:该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。

        rollbackForClassName:该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。

        noRollbackFor:该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。

        noRollbackForClassName:该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。

        在使用的时候要注意:

        1、要配置<tx:annotation-driven transaction-manager="transactionManager" />来开启事务的注解,不配置是没有效果的。

        2、只有uncheck exception才会使事务回滚,checked exception不会使用回滚。如果要在checked exception中让事务回滚,在属性rollbackFor中增加unchecked exception。

        3、readOnly能不用就不用。

        4、注解只有在public声明的类上才会生效。

        没有了没有了!

        

        

                

上一篇下一篇

猜你喜欢

热点阅读