Spring声明式事务

Spring分为编程式事务和声明式事务

声明式事务:

    Spring给了一个约定(AOP开发也给了我们一个约定),如果使用的是声明式事务,那么当你的业务方法不发生异常(或者发生异常,但该异常也被配置信息允许提交事务)时,Spring就会让事务管理器提交事务,而发生异常(并且该异常不被你的配置信息所允许提交事务)时,则让事务管理器回滚事务。

编程式需要自己手动写事务的回滚

    

配置位置文件

      

<?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:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop" 
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/context 
http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd"> 
    <context:property-placeholder location="classpath:db.properties"/>
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="password" value="${jdbc.password}"></property>
                <property name="username" value="${jdbc.username}"></property>
        </bean>
        <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
                    <property name="dataSource" ref="dataSource"></property>
         </bean>
         <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                     <property name="basePackage" value="com.mapper"></property>
                     <!-- 当使用自动注入的时候, -->
                     <property name="sqlSessionFactoryBeanName" value="factory"></property>
         </bean>

        <!-- 声明式事务 -->
        <bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>   
        <!-- 配置声明式事务 -->
        <tx:advice id="txadvice" transaction-manager="txmanager">
                <!-- 设置那些方法需要事务管理 
                方法以in开头的
                -->
                <tx:attributes>

<tx:method name="in*" propagation="REQUIRED"/>
<tx:method name="in*" read-only="true"/>

                </tx:attributes>
        </tx:advice>
        <aop:config>
            <aop:aspect>
                <aop:pointcut expression="execution(* DeclarativeTransaction.*.*())" id="mypoint"/>
                <aop:before method="txadvice" pointcut-ref="mypoint"/>
            </aop:aspect>
        </aop:config>     
</beans>

      Name表示要那些方法需要控制  支持通配符*

     read-only="true"表示只读事务如果true表示只读事务数据库会优化,会对性能由一定的提升,只要是查询的方法建议使用

     false为需要提交的事务

 

  Propagation:控制事务传播,传播行为

       当一个具有事务控制的方法,另外一个具有事务控制的方法调用后,需要如何管理事务

  propagation里面有7个属性:

              REQUIRED(默认值):表示如果当前有事务,就在事务中执行,如果没有就新建一个事务

              SUPPORTS:表示如果当前有事务,就在事务中执行,如果没有就在一个非事务的状态执行

              MANDATORY:必须在事务中执行,如果有事务就在事务中执行,如果没有事务就报错

              REQUIRES_NEW:必须在事务中执行,,表示如果当前没有有事务,就在事务中执行,如果没有就新建一个事务,如果有事务,就把当前事务挂起

              NEVER:必须在非事务中执行,如果没有事务,正常执行,如果有事务,报错

              NOT SUPPORTS ,必须在非事务中执行

              NESTED:必须在事务中执行,如果没有事务就新建事务,如果有事务就嵌套一个事务

   

事务隔离(ioslation):

    在多线程并发访问下保证访问到数据是对的

      1脏读  一个事务(a)读取到了一个事务(b)中未提交的数据,另一个事务可能进行了改变,那此时,a读取到的数据就可能和数据库中的数据可能是不一致的,此时认为数据是脏数据.

      2不可重复读

            主要针对的某一行(列)数据,, 主要针对的是修改数据,不可重复读

                                             两次读在用一个事务内

             当事务a读取到的数据,事务b进行了修改,此时,事务a读取到的不一致,此过程不可读

                解决问题:限制某一列

      3,幻读,

          主要针对的操作是新增,或者删除,他是两次事务的结果

          事务a按照特定的条件查询出结果,事务b新增了一条符合条件的数据,a查询到的数据和数据库中的数据不一致,a事务好像出现了幻觉

            ioslation有五个属性值,分别解决不同的问题

                      DEFAULT:有底层数据自动判断,使用什么隔离级别

                      READ_UNCOMMITTED:可以读取未提交数据,可能出现脏读,不可重复读,,   效率最高

                           READ_COMMITTED  只能读取其他已提交数据,防止脏读,可能出现重复读  

                                REPEATABLE_READ,读取到的数据会被添加锁,防止其他事务修改此事务,防止脏读,重复读,可能出现幻读

                      SERIALIZABLE,排队操作,对整个表添加锁,一个事务在操作时,另一个事务等到(最安全的)

原文地址:https://www.cnblogs.com/jflalove/p/11761338.html