事务疑问

事务疑问

老师,帮忙看看为什么我对batchInsert1/batchInsert2配置了 REQUIRES_NEW;

调用batchAll()时还是全部回滚了?

<?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:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.imooc"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url"
                  value="jdbc:mysql://localhost:3306/imooc_spring_jdbc?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
<!--    JdbcTemplate提供数据CRUD的API  ,id名称最好固定-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>  <!-- ref指向数据源 -->
    </bean>

    <bean id="employeeDao" class="com.imooc.dao.EmployeeDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

    <bean id="employeeService" class="com.imooc.service.EmployeeService">
        <property name="employeeDao" ref="employeeDao"></property>
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

<!--    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">-->
<!--        <property name="dataSource" ref="dataSource"></property>-->
<!--    </bean>-->
<!--    <bean id="hotelDao" class="com.imooc.dao.HotelDao"></bean>-->
    <bean id="hotelService" class="com.imooc.service.HotelService">
        <property name="hotelDao" ref="hotelDao"></property>
    </bean>

    <!--1.复制对应dtd 新增事务schema ;引入aop依赖 -->
    <!-- 1.1事务管理器,用于创建事务/提交/回滚 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--2.事务通知配置,决定哪些方法使用事务,哪些方法不使用事务 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 4.启用声明式事务,成功提交,运行时异常回滚 -->
            <tx:method name="batchAll" propagation="REQUIRED"/>
            <tx:method name="batchInsert1" propagation="REQUIRES_NEW"/>
            <tx:method name="batchInsert2" propagation="REQUIRES_NEW"/>




<!--            <tx:method name="*" propagation="REQUIRED"/>-->
        </tx:attributes>
    </tx:advice>

    <!--3. 定义声明式事务的作用范围-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/><!-- advice-ref指向上面advice id-->
    </aop:config>



</beans>
package com.imooc.service;

import com.imooc.dao.HotelDao;
import com.imooc.entity.Hotel;

import java.util.Date;

public class HotelService {
    private HotelDao hotelDao;
    public void batchAll(){
        batchInsert1();

        if (3==3){
            throw new RuntimeException("出错了---------------------------------");
        }
        batchInsert2();
    }

    public int batchInsert1(){
        int i=1;
        for (i =1;i<=6;i++){

            Hotel hotel=new Hotel();
            hotel.setOrderno(612000l+i);
            hotel.setCity("四川"+i);
            hotel.setPrice(66f);
            hotel.setHotename(" 123");
            hotel.setArrivedate(new Date());
            hotel.setLeavedate(new Date());
            hotelDao.insert(hotel);
        }
        return i-1;


    }
    public int batchInsert2(){
        int i=1;
        for (i =1;i<=6;i++){
            if (i==3){
                //throw new RuntimeException("出错了---------------------------------");
            }
            Hotel hotel=new Hotel();
            hotel.setOrderno(711000l+i);
            hotel.setCity("哈尔滨"+i);
            hotel.setPrice(66f);
            hotel.setHotename(" 123");
            hotel.setArrivedate(new Date());
            hotel.setLeavedate(new Date());
            hotelDao.insert(hotel);
        }
        return i-1;


    }


    public int batchInsert(){
        int i=1;
     for (i =1;i<=6;i++){
         if (i==3){
             throw new RuntimeException("出错了---------------------------------");
         }
         Hotel hotel=new Hotel();
         hotel.setOrderno(58086l+i);
         hotel.setCity("哈尔滨"+i);
         hotel.setPrice(66f);
         hotel.setHotename(" 123");
         hotel.setArrivedate(new Date());
         hotel.setLeavedate(new Date());
         hotelDao.insert(hotel);
     }
     return i-1;


    }


    public HotelDao getHotelDao() {
        return hotelDao;
    }

    public void setHotelDao(HotelDao hotelDao) {
        this.hotelDao = hotelDao;
    }
}
package com.imooc.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class HotelServiceTest {
    @Resource
    HotelService hotelService;

    @Test
    public void batchInsert() {
        int i = hotelService.batchInsert();
        System.out.println("添加了数据数量为:"+i);


    }
    @Test
    public void batchAll() {
        try {
            hotelService.batchAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕小小 2023-01-26 11:33:18

同学你好,REQUIRES_NEW会开启新事务,外层事务不会影响内层事务的提交和回滚操作,但是若内层事务出现异常,则外层事务也会同样进行回滚操作。

已上传的代码中存在的问题:配置文件中未编写hotelDao,建议编写注入hotelDao。

https://img1.sycdn.imooc.com//climg/63d1f2bf09ff0cb508590428.jpg

注:代码上传不完整,无法进行问题的准确定位与代码测试,为了便于问题的准确定位,建议上传完整代码,例如:实体类,Dao层,数据库sql相关代码等。

官方文档教程:https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#tx-propagation-requires_new

祝学习愉快~

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师