• spring 事务


    Spring事务

    以前的事务都是编程式事务,需要开启和关闭,然后程序写在这里面

    spring,声明式事务

    Spring事务隔离级别

    DEFAULT         使用数据库默认隔离级别
    READ_UNCOMMITTED   允许读取尚未提交的数据。可能导致脏读、幻读或不可重复读。
    READ_COMMITTED     允许从已经提交的并发事务读取。可以防止脏读,但依然会出现幻读和不可重复读。
    REPEATABLE_READ     对相同字段的多次读取结果是相同的,除非数据被当前事务改变。可以防止脏读和不可重
                  复读,但幻读依然出现。
    SERIALIZABLE        完全符合ACID的隔离级别,确保不会发生脏读,幻读和不可重复读。


    脏读:    一个事务读取到另一个事务没有提交到的数据。
    不可重复读:   在同一事务中,多次读取同一数据返回的结果不同。
    幻读:    一个事务读取到另一个事务已经提交的事务。

    ==============================================

    Spring事务传播属性

    REQUIRED
      业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务中,
      否则自己创建一个事务。(大部分情况下使用)
    NOT-SUPPORTED
      声明方法需要事务。如果方法没有关联到一个事务,容器会为它开启一个事务,如果方法在
      一个事务中被调用,该事务将会被挂起,在方法调用结束后 ,原先的事务会恢复执行。
    REQUIREDNEW
      业务方法必须在自己的事务中运行。一个新的事务将被启动,而且如果有一个事务正在运行,
      则将这个事务挂起,方法运行结束后,新事务执行结束,原来的事务恢复运行。
      MANDATORY 该方法必须运行在一个现有的事务中,自身不能创建事务,如果方法在没有事务的环境下被调用,
      则会抛出异常。
    SUPPORTS
      如果该方法在一个事务环境中运行,那么就在这个事务中运行,如果在事务范围外调用,那么就在
      一个没有事务的环境下运行。
    NEVER
      表示该方法不能在有事务的环境下运行,如果在有事务运行的环境下调用,则会抛出异常
    NESTED
      如果一个活动的事务存在, 则运行在一个嵌套的事 务中, 如果没 有活动事务, 则按照REQUIRED事
      务方式执行。该事务可以独立的进行提交或回滚,如果回滚不会对外围事务造成影响

    =========================================

    spring事务出现在service层

    1.建立jdbc事务管理器 

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>    

    2.基于xml配置的事务 需要导入schema

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           <!-- 这一句 -->
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    <!-- 这一句 -->
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
    >

    事务通知

    <!-- 事务通知 transaction-manager="transactionManager"跟上面事务管理器的配置的id相同-->    
        <tx:advice id="advice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- method指的是service类中的哪些方法需要加事务,以及加哪种事务 
                    isolation隔离级别    propagation传播属性
                    find*表示只要是以find开头的都加上事务,查询的时候read-only="true"表示只读,性能比较高-->
                <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED"/>
                <tx:method name="find*" read-only="true"/>
                <tx:method name="eidt*"/>
                <tx:method name="del*"/>
            </tx:attributes>
        </tx:advice>    
    <!-- AOP  通知加到哪些类上了 -->
        <aop:config>
            <aop:pointcut expression="execution(* com.kaishengit.service..*.*(..))" id="pt"/>
            <!-- 通知引用上面的id  advice-ref="advice"   pointcut-ref="pt"上面的id-->
            <aop:advisor advice-ref="advice" pointcut-ref="pt"/>
        </aop:config>

    举例

    @Named
    public class StudentService {
    
        @Inject
        private StudentDao studentDao;
        
        
        public void save(Student stu){
            studentDao.save(stu);
            if(1==1){
                throw new RuntimeException();
            }
            studentDao.save(stu);
        }
        
        
        public Student findById(int id) {
            return studentDao.findById(id);
        }
    }        
        

    ============================================

    2.基于于Annotation的事务

    JDBC事务管理器

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>

    基于注解的事务

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

    举例

            
    @Named
    @Transactional
    public class StudentService {
    
        @Inject
        private StudentDao studentDao;
        
        
        public void save(Student stu){
            studentDao.save(stu);
            if(1==1){
                throw new RuntimeException();
            }
            studentDao.save(stu);
        }
        
        @Transactional(readOnly=true)
        public Student findById(int id) {
            return studentDao.findById(id);
        }
    }    


     事务在发生异常的时候才会回滚,如果在service中调用的Dao中的方法,在dao中
    直接try catch掉了,是不会回滚的,使用spring,执行的sql默认是向上抛出运行时异常。意思就是说
    spring默认的 是只有出现运行时异常才会回滚
    if(1==1){
    throw new Exception();
    }

    但是是可以修改的

    @Named
    /*默认的是 @Transactional(rollbackFor=RuntimeException.class)*/
    @Transactional(rollbackFor=Exception.classpublic class StudentService {
    
        @Inject
        private StudentDao studentDao;
        
        
        public void save(Student stu){
            studentDao.save(stu);
            if(1==1){
                throw new RuntimeException();
            }
            studentDao.save(stu);
        }
        
        @Transactional(readOnly=true)
        public Student findById(int id) {
            return studentDao.findById(id);
        }
    }        
  • 相关阅读:
    swift优秀学习博客
    Swift主题色顶级解决方案一
    如何用 Swift 语言构建一个自定控件
    自定义UISlider的样式和滑块
    让你提前知道软件开发(27):创建数据库表和索引
    [6] 算法路
    OGG &quot;Loading data from file to Replicat&quot;table静态数据同步配置过程
    一些书籍和下载链接地址读研究生
    悖论软件测试农药
    Maven直接部署Web应用Tomcat
  • 原文地址:https://www.cnblogs.com/itliucheng/p/4465383.html
Copyright © 2020-2023  润新知