spring-boot学习:十一、spring-boot集成事务

spring-boot事务也就是使用spring事务,业务执行过程中出现异常事务能够自动回滚,避免数据库出现脏数据。

0. 未加事务的demo

1)Mybatis(UserMapper)加入insert方法



    

    
        insert into user(id, name) values (#{id}, #{name})
    


@Repository
public interface UserMapper {

    @Select("select name from user where id = #{id}")
    String findNameById(@Param("id") String id);

    User findUserById(@Param("id") String id);

    int insert(User user);
}

2) 编写UserService,加入insert方法

@Service
public class UserService {
    @Autowired
    private UserMapper userDao;

    public int insert(User user){
        int i= userDao.insert(user);
        if(i==1){
            throw new RuntimeException("error");
        }
        return i;
    }
}

3)编写UserController,提供增加用户的接口

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "addUser")
    public Object addUser(@RequestParam(value = "id")String id, @RequestParam(value = "name")String name){

        User user=new User();
        user.setId(id);
        user.setName(name);
        return userService.insert(user);
    }
}

4. 测试
调用http://127.0.0.1:8081/addUser?id=3&name=kevin3后,返回异常,但数据库却增加了相应的user记录,这显然不是我们想要的,所以需要加入事务。

1. 通过注解的方式

1)在configuration上加@EnableTransactionManagement开启事务,springboot默认开启事务不需要手动加。

2)在service类(方法)上加入@Transactional可开启事务,注意加在类上只针对public的方法有效

package com.kevin.springbootstudy.service;

import com.kevin.springbootstudy.dao.UserMapper;
import com.kevin.springbootstudy.dao.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Autowired
    private UserMapper userDao;

    @Transactional
    public int insert(User user){
        int i= userDao.insert(user);
        if(i==1){
            throw new RuntimeException("error");
        }
        return i;
    }
}

3)再次测试
调用http://127.0.0.1:8081/addUser?id=4&name=kevin4后,返回异常,数据库没有增加相应的user记录,这就是我们想要的结果。

2. 通过xml配置

1)transaction.xml文件


    



	
	



	
		
		
		
		
	




2)引入文件@ImportResource(“classpath:transaction.xml”)

3. aop全局配置事务

1)pom.xml引入aop



	org.springframework.boot
	spring-boot-starter-aop

2)增加一个事务管理的类

@Aspect
@Configuration
public class TransactionAdviceConfig {
	
	private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.***.service..*.*(..))";

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean
    public TransactionInterceptor txAdvice() {

        DefaultTransactionAttribute txRequired = new DefaultTransactionAttribute();
        txRequired.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        DefaultTransactionAttribute txRequiredReadonly = new DefaultTransactionAttribute();
        txRequiredReadonly.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        txRequiredReadonly.setReadOnly(true);

        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        source.addTransactionalMethod("get*", txRequiredReadonly);
        source.addTransactionalMethod("query*", txRequiredReadonly);
        source.addTransactionalMethod("find*", txRequiredReadonly);
        source.addTransactionalMethod("*", txRequired);

        return new TransactionInterceptor(transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}

3)部分方法需要单独处理事务,也可以配合@Transactional一起使用

易错点(@Transactional):

1)spring推荐在具体类上使用@Transactional,而不是在接口上声明

2)@Transactional声明在类上,则对所有的public方法有效

3)使用了@Transactional的方法,被同一个类里面的未使用@Transactional的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。

注:目录结构如下
spring-boot学习:十一、spring-boot集成事务_第1张图片
参考
https://docs.spring.io/spring/docs/5.1.4.RELEASE/spring-framework-reference/data-access.html#transaction-declarative

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html

https://blog.csdn.net/nextyu/article/details/78669997

你可能感兴趣的:(spring-boot)