事务的应用

Posted bulrush

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务的应用相关的知识,希望对你有一定的参考价值。

我们在service中写上两个方法,一个是加钱,一个是减钱。都添加上事务。

场景A:

 1 /**
 2      * 加钱
 3      * @param userId
 4      */
 5     @Transactional
 6     public void updateAdd(Integer userId){
 7         User user_add = userMapper.findUserById(userId);
 8         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
 9         user_add.setMoney(user_add.getMoney().add(bigDecimal));
10         userMapper.update(user_add);
11     }
 1 /**
 2      * 减钱
 3      * @param userId
 4      */
 5     @Transactional
 6     public void updateLessen(Integer userId){
 7         User user_lessen = userMapper.findUserById(userId);
 8         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
 9         user_lessen.setMoney(user_lessen.getMoney().subtract(bigDecimal));
10         userMapper.update(user_lessen);
11     }

测试:

@Test
    public void test03(){
        //同时调用一个用户加钱,一个用户减钱。
        userService.updateAdd(3);
        userService.updateLessen(4);
    }

没有任何问题

下面修改一下。

场景B:

1 @Transactional
2     public void updateAdd(Integer userId){
3         User user_add = userMapper.findUserById(userId);
4         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
5         user_add.setMoney(user_add.getMoney().add(bigDecimal));
6         userMapper.update(user_add);
7         updateLessen(4);
8     }
 1 /**
 2      * 减钱
 3      * 如果当前存在事务,则挂起当前事务并且开启一个新事物继续执行,新事物执行完毕之后,
 4      * 然后在缓刑之前挂起的事务,如果当前不存在事务的话,则开启一个新事物。
 5      * @param userId
 6      */
 7     @Transactional(propagation = Propagation.REQUIRES_NEW)
 8     public void updateLessen(Integer userId){
 9         User user_lessen = userMapper.findUserById(userId);
10         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
11         user_lessen.setMoney(user_lessen.getMoney().subtract(bigDecimal));
12         userMapper.update(user_lessen);
13     }

测试:

1 @Test
2     public void test03(){
3         //同时调用一个用户加钱,一个用户减钱。
4         userService.updateAdd(3);
5         //userService.updateLessen(4);
6     }

这也没有任何问题。

下面给减钱的抛出异常:

场景C:

1  @Transactional(propagation = Propagation.REQUIRES_NEW)
2     public void updateLessen(Integer userId){
3         User user_lessen = userMapper.findUserById(userId);
4         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
5         user_lessen.setMoney(user_lessen.getMoney().subtract(bigDecimal));
6         userMapper.update(user_lessen);
7         throw new RuntimeException("此处发生异常");
8     }

结果:两个都回滚了。

可能有的小伙伴要说了,updateAdd() 抛出了异常在updateLessen() 没有进行捕获,造成了updateAdd()也是抛出了异常了的!所以他们两个都会回滚!

场景D:

 1  @Transactional
 2     public void updateAdd(Integer userId){
 3         User user_add = userMapper.findUserById(userId);
 4         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
 5         user_add.setMoney(user_add.getMoney().add(bigDecimal));
 6         userMapper.update(user_add);
 7 
 8         try {
 9             updateLessen(4);
10         } catch (RuntimeException re) {
11             re.printStackTrace();
12         }
13     }

结果:这两个事务中的数据,数据库中都进行改变了。

场景C相当于:

@Transactional
    public void updateAdd(Integer userId){
        User user_add = userMapper.findUserById(userId);
        BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
        user_add.setMoney(user_add.getMoney().add(bigDecimal));
        userMapper.update(user_add);

            //updateLessen(4);
            User user_lessen = userMapper.findUserById(userId);
            user_lessen.setMoney(user_lessen.getMoney().subtract(bigDecimal));
            userMapper.update(user_lessen);
            throw new RuntimeException("此处发生异常");
        
    }

updateAdd()事务中抛出了异常。

场景D相当于:

 1 @Transactional
 2     public void updateAdd(Integer userId){
 3         User user_add = userMapper.findUserById(userId);
 4         BigDecimal bigDecimal = BigDecimal.valueOf(10.99);
 5         user_add.setMoney(user_add.getMoney().add(bigDecimal));
 6         userMapper.update(user_add);
 7 
 8         try {
 9             //updateLessen(4);
10             User user_lessen = userMapper.findUserById(userId);
11             user_lessen.setMoney(user_lessen.getMoney().subtract(bigDecimal));
12             userMapper.update(user_lessen);
13             throw new RuntimeException("此处发生异常");
14         } catch (RuntimeException re) {
15             re.printStackTrace();
16         }
17     }

updateAdd() 中抛出了异常,但是捕获了异常。




以上是关于事务的应用的主要内容,如果未能解决你的问题,请参考以下文章

BottomNavigationView 滞后于片段事务

理解片段事务期间片段的生命周期方法调用

提交带有全屏片段的片段事务

如果在动画正在进行时单击,Android Fragment 事务动画会崩溃

使用 OnItemClickListener 列出视图片段到片段事务

Android从后台堆栈中删除事务