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“还存在

 

原文地址:https://www.cnblogs.com/jonsnow/p/6654569.html