欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring(十三)-- Spring 事务

程序员文章站 2022-12-24 12:48:34
Spring 事务 1. 回忆之前事务知识点 一:事务的概念 将一系列的数据操作捆绑在一起,成为一个整体进行统一管理! 一条或者多条sql语句的集合! 二:事务的ACID特性 原子性(Atomicity):在事务中的操作,要么都执行,要么都不执行! 一致性(Consistency):事务必须保证数据 ......

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

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

4. 创建service层和impl

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

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

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

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>

 

  测试方法代码

Spring(十三)-- Spring 事务

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>

 

  测试方法代码

Spring(十三)-- Spring 事务

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

Spring(十三)-- Spring 事务

Spring(十三)-- Spring 事务

  测试代码和aspectj一样

Spring(十三)-- Spring 事务