# spring-transcation **Repository Path**: MarkPolaris/spring-transcation ## Basic Information - **Project Name**: spring-transcation - **Description**: spring通过注解实现事务 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-07-27 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### 通过注解事务完成转账案例 ##### 一、转账基本逻辑 1. 需要额外添加的xml配置有 ```xml ``` 2. 写一个转账的小demo,定义相关实体类Account ![5d3cfe72530ca54136](https://i.loli.net/2019/07/28/5d3cfe72530ca54136.png) ```java package com.neuedu.entity; import lombok.Data; import java.math.BigDecimal; /** * @Author: MARK * @Date: 2019/7/27 16:07 * @version: 1.0.0 * @Description: */ @Data public class Account { private Integer id; private String name; private BigDecimal money; } ``` 3. DAO层使用mybatis,写一个mapper,将id和金额传进去,通过map ```java package com.neuedu.mapper; import org.springframework.stereotype.Repository; import java.util.Map; /** * @Author: MARK * @Date: 2019/7/27 16:07 * @version: 1.0.0 * @Description: */ @Repository public interface AccountMapper { //更新该账户的金额 void update(Map map); } ``` 4. mapper的实现AccountMapper.xml ```xml update account set money = money + #{money} where id=#{id} ``` 5. 业务层,AccountService接口 ```java package com.neuedu.service; import java.math.BigDecimal; /** * @Author: MARK * @Date: 2019/7/27 16:07 * @version: 1.0.0 * @Description: */ public interface AccountService { //谁给谁转了多少钱 void transfer(Integer id1, Integer id2, BigDecimal money); } ``` 6. 业务层接口的实现类AccountServiceImpl.java ```java package com.neuedu.service.impl; import com.neuedu.mapper.AccountMapper; import com.neuedu.service.AccountService; import jdk.management.resource.internal.inst.UnixAsynchronousServerSocketChannelImplRMHooks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; /** * @Author: MARK * @Date: 2019/7/27 16:07 * @version: 1.0.0 * @Description: */ @Service public class AccountServiceImpl implements AccountService { @Autowired private AccountMapper accountMapper; @Override public void transfer(Integer id1, Integer id2, BigDecimal money) { //两个账户分别更新 //账户1减钱 Map map1 = new HashMap<>(); map1.put("id", id1); map1.put("money", money.multiply(new BigDecimal(-1))); accountMapper.update(map1); //账户2加钱 Map map2 = new HashMap<>(); map2.put("id", id2); map2.put("money", money); accountMapper.update(map2); } } ``` 环绕通知加不加都可以,加的话注意写上执行方法 proceedingJoinPoint.proceed(); 7. 先对mapper进行测试,通过后再对service进行测试,service测试如下 ```java package com.neuedu.service; import com.neuedu.AppTest; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import java.math.BigDecimal; import static org.junit.Assert.*; /** * @Author: MARK * @Date: 2019/7/28 09:15 * @version: 1.0.0 * @Description: */ @Slf4j public class AccountServiceTest extends AppTest { @Autowired private AccountService accountService; @Test public void testService(){ accountService.transfer(1, 2, new BigDecimal(500)); } } ``` 8. 运行结果 运行前数据库 ![5d3d008f29b0785019](https://i.loli.net/2019/07/28/5d3d008f29b0785019.png)         运行后数据库 ![5d3d00dc139a325001](https://i.loli.net/2019/07/28/5d3d00dc139a325001.png) 基本逻辑完成,下面对事务进行测试 #### 二、事务处理 1. 在转账过程中添加异常 ![5d3d01c4c08b671050](https://i.loli.net/2019/07/28/5d3d01c4c08b671050.png) 2. 再运行测试,抛出异常 ![5d3d023e0649472428](https://i.loli.net/2019/07/28/5d3d023e0649472428.png) 3. 查看数据库, 发现id为1的money减少了500,而id为2的money没有变化,这就是要添加事务的原因 ![5d3d025dcbd1c89661](https://i.loli.net/2019/07/28/5d3d025dcbd1c89661.png) 4. 添加事务注解 ![5d3d031f378b536510](https://i.loli.net/2019/07/28/5d3d031f378b536510.png) 5. 再运行测试 ![5d3d039075e9223220](https://i.loli.net/2019/07/28/5d3d039075e9223220.png) 同样抛出异常,但是由于添加了事务注解,出现异常全部回滚