异步事务?关于异步@Async + 事务@Transactional的结合使用问题分析【享学Spring MVC】(下)

简介: 异步事务?关于异步@Async + 事务@Transactional的结合使用问题分析【享学Spring MVC】(下)

场景三:


@Slf4j
@Service
public class HelloServiceImpl implements HelloService {
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Transactional
    @Override
    public void enter(Integer age) {
        System.out.println("enter的线程:" + Thread.currentThread().getName());
        String name = "fsx-" + age;
        String sql = "insert into user (name,age) values ('" + name + "'," + age + ")";
        jdbcTemplate.update(sql);
        // 进来后开始吃饭(但因为吃饭比较耗时  所以放到Async异步线程里去做)
        applicationContext.getBean(HelloService.class).eat(age);
        applicationContext.getBean(HelloService.class).play(age);
    }
    @Transactional // 因为吃饭也需要原子 所以也加上事务惊醒控制
    @Async
    @Override
    public void eat(Integer age) {
        System.out.println("eat的线程:" + Thread.currentThread().getName());
        String name = "eat-" + age;
        String sql = "insert into eat (eat_name) values ('" + name + "')";
        jdbcTemplate.update(sql);
        throw new RuntimeException("eat抛出运行异常");
    }
    @Transactional
    @Async
    @Override
    public void play(Integer age) {
        System.out.println("play的线程:" + Thread.currentThread().getName());
        String name = "play-" + age;
        String sql = "insert into play (play_name) values ('" + name + "')";
        jdbcTemplate.update(sql);
        throw new RuntimeException("play抛出运行异常");
    }
}


请注意示例区别:enter方法并没有主动throw抛出异常。

现象:user表插入成功。eat和play表均插入无效(被回滚)

结论:同上


场景四:


此场是我模拟的最后一个场景:异步线程里继续调用异步线程,并且加上事务


@Slf4j
@Service
public class HelloServiceImpl implements HelloService {
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Transactional
    @Override
    public void enter(Integer age) {
        System.out.println("enter的线程:" + Thread.currentThread().getName());
        String name = "fsx-" + age;
        String sql = "insert into user (name,age) values ('" + name + "'," + age + ")";
        jdbcTemplate.update(sql);
        // 进来后开始吃饭(但因为吃饭比较耗时  所以放到Async异步线程里去做)
        applicationContext.getBean(HelloService.class).eat(age);
    }
    @Transactional // 因为吃饭也需要原子 所以也加上事务惊醒控制
    @Async
    @Override
    public void eat(Integer age) {
        System.out.println("eat的线程:" + Thread.currentThread().getName());
        String name = "eat-" + age;
        String sql = "insert into eat (eat_name) values ('" + name + "')";
        jdbcTemplate.update(sql);
        applicationContext.getBean(HelloService.class).play(age);
        throw new RuntimeException("eat抛出运行异常");
    }
    @Transactional
    @Async
    @Override
    public void play(Integer age) {
        System.out.println("play的线程:" + Thread.currentThread().getName());
        String name = "play-" + age;
        String sql = "insert into play (play_name) values ('" + name + "')";
        jdbcTemplate.update(sql);
    }
}


请注意此示例区别:enter里没主动抛出异常。enter异步调用eat,eat再异步调用play,并且play里没有抛出异常


现象:user插入成功。eat插入无效(被回滚),play插入成功

结论:不同线程之间的事务完全隔离,异步线程内仍是可以调用异步~


总结


本文没有新的内容,源于跟一个小伙伴讨论这块时,自己也有些打鼓的地方,因此就写了本文做一个记录,还好所有结论和我"预估"的保持一致。


本文主要是把异步@Async和事务@Transactional结合使用的一个场景来进行分析,因为开发中也比较常见,因此希望把这两块内容集合使用做些示例,希望可以做到心中有数,这样使用起来才会更加的胸有成竹嘛~

相关文章
|
18天前
|
Java 数据库 开发者
|
2天前
|
SQL Java 关系型数据库
Spring 事务
Spring 事务
6 1
|
5天前
|
Java 数据库连接 数据库
Spring事务简介,事务角色,事务属性
Spring事务简介,事务角色,事务属性
15 2
|
9天前
|
Java 数据库连接 数据库
16:事务-Java Spring
16:事务-Java Spring
25 5
|
10天前
|
消息中间件 Java 关系型数据库
Spring事务与分布式事务
这篇文档介绍了事务的概念和数据库事务的ACID特性:原子性、一致性、隔离性和持久性。在并发环境下,事务可能出现更新丢失、脏读和不可重复读等问题,这些问题通过设置事务隔离级别(如读未提交、读已提交、可重复读和序列化)来解决。Spring事务传播行为有七种模式,影响嵌套事务的执行方式。`@Transactional`注解用于管理事务,其属性包括传播行为、隔离级别、超时和只读等。最后提到了分布式事务,分为跨库和跨服务两种情况,跨服务的分布式事务通常通过最终一致性策略,如消息队列实现。
|
12天前
|
监控 Java 测试技术
Spring Boot与事务钩子函数:概念与实战
【4月更文挑战第29天】在复杂的业务逻辑中,事务管理是确保数据一致性和完整性的关键。Spring Boot提供了强大的事务管理机制,其中事务钩子函数(Transaction Hooks)允许开发者在事务的不同阶段插入自定义逻辑。本篇博客将详细探讨事务钩子函数的概念及其在Spring Boot中的应用。
34 1
|
12天前
|
监控 Java API
Spring Boot与异步任务:整合与应用场景
【4月更文挑战第29天】异步任务在现代应用程序开发中扮演着重要的角色,它们可以提高应用程序的性能和响应速度,尤其适用于处理长时间运行的任务或需要等待外部资源的场景。Spring Boot提供了强大的支持来简化异步任务的实现。
23 0
|
15天前
|
XML Java 数据库连接
精妙绝伦:玩转Spring事务编程的艺术
【4月更文挑战第20天】
30 0
|
22天前
|
XML Java 数据库
在Spring框架中,XML配置事务
在Spring框架中,XML配置事务
|
22天前
|
Java 数据库连接 数据库
spring事务失效(疑难杂症)
spring事务失效(疑难杂症)