• Spring 事务传播行为


    事务的传播行为
    一个事务方法调用另一个事务方法时,如何进行事务控制。是做为外部事务的整体控制?还是做为内部事务的部分控制?
    在@Transactional注解中,使用propagation属性指导事务的传播行为。

    //required -- 有事务就行(事务默认传播行为)
    @Transactional(propagation=Propagation.REQUIRED)
    
    //required new -- 使用自己的事务,外面调用的方法的事务被挂起,相当于外面的事务失效
    @Transactional(propagation=Propagation.REQUIRES_NEW)

    下一面看一个实例:

    1.做两个接口IInfoDao和IWorkDao

    package maya.dao;
    
    public interface IInfoDao {
        public void delete(String code);
    }
    package maya.dao;
    
    public interface IWorkDao {
        public void deleteByInfoCode(String code);
    }

    2.做两个类继承以上两个接口:InfoDao和WorkDao

    package maya.daolmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import maya.dao.IInfoDao;
    @Repository
    public class InfoDao implements IInfoDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        @Override
        public void delete(String code) {
            
       //添加一个判定条件,制造一个错误
       if (code.equals("p009")) {
                int n = 5/0;
         }
         String sql = "delete from info where code=?";
         jdbcTemplate.update(sql,code);        
        }
    }
    package maya.daolmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import maya.dao.IWorkDao;
    @Repository
    public class WorkDao implements IWorkDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        @Override
        public void deleteByInfoCode(String code) {
            String sql = "delete from work where infoCode=?";
            jdbcTemplate.update(sql,code);        
        }
    }

    3.向xml文件 添加配置信息

    <?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"
        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-4.3.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    
    <!--启动自动扫描。扫描以下包里的类,以备使用-->
    <context:component-scan base-package="maya.daolmpl,maya.servicelmpl"></context:component-scan>
    <!--引入db.properties文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 生成连接池 -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
        <property name="minPoolSize" value="${minPoolSize}"></property>
        <property name="maxPoolSize" value="${maxPoolSize}"></property>
        <property name="initialPoolSize" value="${initialPoolSize}"></property>
    </bean>
    
    <!-- 生成jdbcTemplate -->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置事务管理器 -->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 启动事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    </beans>

    4.1建立业务接口并用类继承

    IInfoService接口

    package maya.service;
    public interface IInfoService {
        public void delete(String code);
    }

    InfoService类

    package maya.servicelmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.daolmpl.WorkDao;
    import maya.service.IInfoService;
    @Service
    public class InfoService implements IInfoService {
        @Autowired
        private IWorkDao workDao;
        @Autowired
        private IInfoDao infoDao;
        
        //有事务就行(事务默认传播行为)
        @Transactional(propagation=Propagation.REQUIRED)
        
        @Override
        public void delete(String code) {
            workDao.deleteByInfoCode(code);
            infoDao.delete(code);        
        }
    }

    5.创建测试类并运行

    package maya.servicelmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    
    import maya.service.IInfoService;
    
    @Component
    public class TestAll {
        @Autowired
        private IInfoService infoService;
        @Transactional
        public void deleteMany() {
            infoService.delete("p008");
            infoService.delete("p009");
        }
    }
    package maya.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.service.IInfoService;
    import maya.servicelmpl.TestAll;
    
    
    public class Test {
        private static ApplicationContext context = null;
        private static IInfoDao infoDao = null;
        private static IWorkDao workDao = null;
        private static IInfoService infoService = null;
        private static TestAll testAll = null;
        static {
            context = new ClassPathXmlApplicationContext("beans.xml");
            infoDao = (IInfoDao)context.getBean("infoDao");
            workDao = (IWorkDao)context.getBean("workDao");
            infoService = (IInfoService)context.getBean("infoService");
            testAll = (TestAll)context.getBean("testAll");
        }
        
        public static void main(String[] args) {
            testAll.deleteMany();
        }    
    }

    运行结果:”p008“、“p009”未被删除

    4.2设置使用自己的事务,外面调用的方法的事务被挂起

    package maya.servicelmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.daolmpl.WorkDao;
    import maya.service.IInfoService;
    @Service
    public class InfoService implements IInfoService {
        @Autowired
        private IWorkDao workDao;
        @Autowired
        private IInfoDao infoDao;
        
        //使用自己的事务,外面调用的方法的事务被挂起,相当于TestAll.java中的事务失效
        @Transactional(propagation=Propagation.REQUIRES_NEW)
        @Override
        public void delete(String code) {
            workDao.deleteByInfoCode(code);
            infoDao.delete(code);        
        }
    }

    运行结果(由于TestAll.java中的事务失效):“p008”已被删除,”p009“还存在

     

  • 相关阅读:
    iOS 开发中的坑与相关技巧
    SDK 封装的相关看法
    线程问题---在iPad上会崩溃,在iPhone上不会崩溃
    添加新手引导页需要注意的几个小点
    iOS 七牛云上传并获取图片----【客户端】
    iOS 线程相关-----绝对de干货
    Vue.js 基础示例
    lib-flexible 结合 WKWebView 的样式错乱解决方法
    基于CommentCoreLibrary简单的弹幕实现
    页面上动态编译及执行java代码
  • 原文地址:https://www.cnblogs.com/jonsnow/p/6654569.html
Copyright © 2020-2023  润新知