zoukankan      html  css  js  c++  java
  • 初识事物处理

      业务层的职能不仅仅是调用dao这么简单,事物处理是任何企业级应用开发中不能回避的一个重要问题。意为我们通过在业务中硬编码的方式

    进行事物控制,这样的弊端显而易见:事物代码分散在业务方法中难以重用,需要调整时工作量也比较打:复杂事物的编码难度较高,增加了开发

    难度等。spring提供了声明事物处理机制,他基于aop实现,无须编写任何事物管理代码,所有的工作全部在配置文件中完成。这意味着与业务代码

    完全分离,配置即可用,降低了开发和维护的难度。

    定义事物管理器

    <bean id="txManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
            <!-- ref为数据源 -->
            <property name="dataSource" ref="dataSource"></property>
        </bean>

    指定的事物管理器设置事物属性

        <!--  事物管理器id为transactionMapper则可以省略 transaction-manager此属性  -->
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <!-- 定义属性,声明事物规则 -->
            <tx:attributes>
                <!-- propagation属性定义事物传播行为  name属性则是对应的方法 以什么开头的-->
                <tx:method name="find*" propagation="SUPPORTS"/>
                <tx:method name="add*" propagation="REQUIRED"/>
                <tx:method name="del*" propagation="REQUIRED"/>
                <tx:method name="update*" propagation="REQUIRED"/>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>

    propagetion:事务传播机制,该属性可选值有以下几种

    1. REQUIRED:默认值,表示如果存在一个事务,则支持当前事务,如果当前没有事务,则开启一个新的事务
    2. REQUIRES_NEW:表示总是开启一个新的事务,如果事物以及存在则将这个存在的事务挂起,开启新的事务执行该方法
    3. MANDATORY:表示如果存在一个事务,则支持当前事务,如果当前没有一个活动的事务,则抛出异常
    4. NESTED:表示如果存在一个活动的事务,则创建一个事务作为当前事务的嵌套事务运行:如果没有当前事务,该取值与REQUIRED相同
    5. SUPPORTS:表示如果存在一个事务,则支持当前事务,如果当前没有事务,则按非事物方式执行
    6. NOT_SUPPORTED:表示总是以非事物方式执行。如果事物已经存在,则将这个存在的事物挂起,然后执行该方法
    7. NEVER:表示总是以非事物方式执行。如果当前存在一个活动的事物,则抛出异常

    使用注解实现事务处理

     使用了注解就不需要再声明事物规则

    只需要一行就行了如下

    <tx:annotation-driven transaction-manager="txManager"/>

    剩下的声明事物规则就交给注解处理了如下

    在业务类上添加@Transaction注解即可为该类的所有业务方法统一添加事物处理。如果某业务方法需要采用不同的事务规则,可以在该业务方法添加@Transaction注解

    单独进行设置。@Transaction注解也可以设置事物属性的值,默认的@Transaction设置如下

    1. 事务传播设置是:REQUIRED
    2. 事务隔离级别是:
    3. 事务是读写
    4. 事务超时默认是依赖于事物系统的,或者事务超时没有被支持
    5. 任何RuntimeException将触发事务回滚,但是任何checked exception将不触发事务回滚

    @Transaction注解各属性如下

     

    需要注意的点:

    @Transactional只能被应用到public方法上,对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.

    SOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别

    使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应

    2. ISOLATION_READ_UNCOMMITTED 未提交读

    事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读

    3. ISOLATION_READ_COMMITTED 提交读

    保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

    4. ISOLATION_REPEATABLE_READ 可重复读

     这种事务隔离级别可以防止脏读,不可重复读。但可能出现幻像读。除了保证一个事务不能读取另一个事务未提交的数据外,还保证避免下面的情况产生(不可重复读)

    5. ISOLATION_SERIALIZABLE串行读

     花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除防止脏读,不可重复读外,还避免幻像读。

    什么是脏数据,脏读,不可重复读,幻觉读?

    Dirty reads--读脏数据。

    比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的 

    non-repeatable reads--不可重复读。

    比如事务A中两处读取数据-total-的值。在第一读的时候,total100,然后事务B就把total的数据改成200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱 

    phantom reads--幻象读数据。

    这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="grace",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"grace",结果取出来了7个数据。

    不可重复读的重点是修改    同样的条件, 读取过的数据, 再次读取出来发现值不一样。

    幻读的重点在于新增或者删除:同样的条件, 1次和第2次读出来的记录数不一样。

    而事务的隔离级别会导致读取到非法数据的情况如下表示:

     

    Dirty reads

    non-repeatable reads

    phantom reads

    SERIALIZABLE

    不会

    不会

    不会

    REPEATABLE_READ

    不会

    不会

    READ_COMMITTED

    不会

    READ_UNCOMMITTED

     

    常用数据库默认事务隔离级别

    MySQL默认为REPEATABLE_READ

    SQLSERVER:默认为READ_COMMITTED

    oracle默认为READ_COMMITTED

     

  • 相关阅读:
    假期学习2
    假期学习1
    读《需求工程--软件建模和分析》一
    数据清洗
    Mapreduce实例——WordCount
    SEVEN python环境jieba分词的安装 以即热词索引
    SIX Spark Streaming 编程初级实践
    FIVE Spark SQL 编程初级实践
    FOUR spark-shell 交互式编程
    THREE SPAKR
  • 原文地址:https://www.cnblogs.com/hfx123/p/9706039.html
Copyright © 2011-2022 走看看