• Spring(十三)-- Spring 事务


    Spring 事务

    1. 回忆之前事务知识点

     一:事务的概念

               将一系列的数据操作捆绑在一起,成为一个整体进行统一管理!

               一条或者多条sql语句的集合!

     二:事务的ACID特性

           原子性(Atomicity):在事务中的操作,要么都执行,要么都不执行!

           一致性(Consistency):事务必须保证数据从一个一致性的状态到达另一个一致性的状态!

           持久性(Durability):事务一旦提交,对数据库的数据影响是永久性的!

           隔离性(Isolation):每个事务之前互不干扰!

     三: 事务创建的原则:

          1.事务尽可能简短

              因为启动事务之后,数据库管理系统需要保留大量资源来保证事务的ACID!

              如果是多用户的系统,那么会严重影响我们的系统性能!

          2.事务中访问的数据量要小

              在并发的情况下,执行事务,事务的访问量越小,各个线程之前对数据的

              争夺就越小!

          3.查询时尽量不使用事务

              因为查询不会修改数据!

          4.在事务处理过程中,尽量不要出现用户等待的情况

               如果登台事件过程,占用资源太久,有可能造成系统阻塞!

    四: 必须掌握事务中的两个属性

          1.Isolation:五种事务隔离级别

              01.default:采用数据库默认的事务隔离级别

                   mysql:repeatable-read(可重复读取)

                   oracle:read-committed(读提交)

              02.repeatable-read(可重复读取):解决了脏读和不可重复读,但是有可能发生幻读(通过其他的锁机制解决)!

              03.read-committed(读提交):解决了脏读,但是没解决不可重复读

              04.read-uncommitted(读未提交):什么都没有解决!

              05.serializable(串行化):解决并发的问题!

          2.Propagation:七种事务传播行为

               01.required:是spring默认的事务传播行为!

                            指定的方法必须在事务内执行,

                            如果没有事务,自动创建事务并执行!

               02.supports:有没有事务都执行!

                            有事务就在事务中执行,否则直接执行!

               03.mandatory:如果当前存在事务,就执行该事务,

                             如果当前不存在事务,就抛出异常。

               04.requires_new:总是创建新事务,

                              如果当前方法存在事务,则当前事务挂起,

                              直到新创建的事务执行完毕!

               05.not_supported:不能在事务中执行,

                                如果当前方法存在事务,则当前事务挂起!

               06.never:     不能在事务中执行,

                               如果当前方法存在事务,则抛出异常。

               07.nested:如果当前存在事务,则在嵌套事务内执行。

                          如果当前没有事务,则执行与requires_new类似的操作。

        requires_new 启动一个新的, 不依赖于环境的 "内部" 事务.

        这个事务将被完全 commited 或 rolled back 而不依赖于外部事务,

        它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时,

         外部事务将被挂起,内务事务结束时, 外部事务将继续执行.

         另一方面, nested 开始一个 "嵌套的" 事务,

         它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,

          它将取得一个 savepoint. 如果这个嵌套事务失败,

          我们将回滚到此 savepoint. 潜套事务是外部事务的一部分,

          只有外部事务结束后它才会被提交.

        由此可见, requires_new 和 nested 的最大区别在于,

          requires_new 完全是一个新的事务,

           nested 则是外部事务的子事务,

          如果外部事务 commit, 潜套事务也会被 commit,

          这个规则同样适用于 roll back.

    2. 创建需要的数据库语句

     DROP TABLE IF EXISTS `account`;

               CREATE TABLE `account` (

                 `aid` int(10) NOT NULL AUTO_INCREMENT,

                 `balance` double DEFAULT NULL,

                 `aname` varchar(20) DEFAULT NULL,

                 PRIMARY KEY (`aid`)

               ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

               insert  into `account`(`aid`,`balance`,`aname`) values (1,10000,'张三');

               DROP TABLE IF EXISTS `stock`;

               CREATE TABLE `stock` (

                 `sid` int(10) NOT NULL AUTO_INCREMENT,

                 `sname` varchar(20) DEFAULT NULL,

                `amount` int(10) DEFAULT NULL,

                 PRIMARY KEY (`sid`)

               ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

               insert  into `stock`(`sid`,`sname`,`amount`) values (1,'张三',0);

    3. 创建dao层和impl

    4. 创建service层和impl

    5. 创建需要的异常类 jdbc.properties文件

    6. 使用AspectJ实现事务的管理xml配置文件

     <!--  01.引入  jdbc文件-->
        <context:property-placeholder location="classpath:jdbc.properties"/>
    
        <!--  02.配置数据源-->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="${jdbc.driverClass}"/>
              <property name="url" value="${jdbc.jdbcUrl}"/>
              <property name="username" value="${jdbc.userName}"/>
              <property name="password" value="${jdbc.password}"/>
        </bean>
    
        <!--03.配置dao层-->
        <bean id="accountDao" class="com.xdf.dao.impl.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <bean id="stockDao" class="com.xdf.dao.impl.StockDaoImpl">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--04.配置service层-->
       <bean id="buyStockService" class="com.xdf.service.BuyStockServiceImpl">
           <property name="accountDao" ref="accountDao"/>
           <property name="stockDao" ref="stockDao"/>
       </bean>
    
    
    
        <!--05.无论使用什么方式 都必须创建事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
               <property name="dataSource" ref="dataSource"/>
         </bean>
    
        <!--06. 使用AspectJ 实现spring对事务的管理-->
       <tx:advice id="myAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="com.xdf.service.BuyStockException"/>
        </tx:attributes>
    </tx:advice>
    
        <!-- 07.配置切入点-->
        <aop:config>
             <aop:pointcut id="myPoint" expression="execution(* *..service.*.*(..))"/>
             <aop:advisor advice-ref="myAdvice" pointcut-ref="myPoint"/>
        </aop:config>

      测试方法代码

    7. 使用事务工厂实现事务的管理xml配置文件

    <!--06.使用事务工厂-->
    <bean id="proxyFactoryBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!--配置事务管理器-->
        <property name="transactionManager" ref="transactionManager"/>
        <!--配置目标对象-->
        <property name="target" ref="buyStockService"/>
        <!--配置切点-->
        <property name="transactionAttributes">
            <props>
                <!--指定切入点
                 01.事务隔离级别
                 02.事务传播行为
                 03.发生什么异常时?是回滚还是提交    - 回滚    +提交
                 -->
                <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
            </props>
        </property>

      测试方法代码

    8. 使用注解实现事务的管理xml配置文件

      测试代码和AspectJ一样

  • 相关阅读:
    oracle锁---原理篇
    SML + NL + HJ
    Oracle中varchar,varchar2,nvarchar,nvarchar2的区别
    oracle 一致读原理
    commit 流程
    IMPDP NETWORK_LINK参数
    WINDOWS访问虚拟机RedHat搭配的Apache2服务器
    初识malloc函数
    好吧,又失眠
    休息一天
  • 原文地址:https://www.cnblogs.com/fl72/p/9667832.html
Copyright © 2020-2023  润新知