ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring事务传播行为二

2022-09-12 19:04:08  阅读:188  来源: 互联网

标签:事务 buy currentThread Thread Spring getName product 传播 println


接着上一篇章继续说

这个需要结合着具体的案例来进行分析。

结合着我之前写的一篇文章:事务失效

看下代码:

@Transactional
public void sellProduct() throws ClassNotFoundException {
    log.info("----------------->>>>>>>开启日志<<<<<------------------------");
    LOCK.lock();
    try {
        System.out.println(Thread.currentThread().getName() + ":抢到锁了,进入到方法中来");
        // 首先查询库存
        Product product = productMapper.selectById(1L);
        Integer productcount = product.getProductcount();
        System.out.println(Thread.currentThread().getName() + ":当前库存是:" + productcount);
        if (productcount > 0) {
            product.setProductcount(productcount - 1);
            // 更新操作
            productMapper.updateById(product);
            Buy buy = new Buy();
            buy.setProductname(product.getProductname());
            buy.setUsername(Thread.currentThread().getName());
            // 保存操作
            buyMapper.insert(buy);
            System.out.println(Thread.currentThread().getName() + ":减库存,创建订单完毕!");
        } else {
            System.out.println(Thread.currentThread().getName() + ":没有库存了");
        }
    } finally {
        System.out.println(Thread.currentThread().getName() + ":释放锁");
        // 释放锁
        LOCK.unlock();
    }
}

首先分析,多个线程进来的时候,都将开启一个新的数据库连接。但是因为使用了LOCK锁,那么这里达到的效果就是多个线程拥有的自己的数据库连接,但是在当前来说,只有一个线程在操作数据库连接。

这是一种明显的使用错误情况。因为只要一个线程在执行,而其他持有数据库连接的线程就只能够等待。数据库连接是非常宝贵的资源了。但是在这里的代码中,却是没有使用。但是却一直持有,效率很低。所以针对这种情况,需要来进行处理。

最主要的原因在于:锁都已经释放了,但是数据库连接还没有提交事务

这种情况,代价最低的解决方式,我觉得类似如下结构:

public void sellProduct() throws ClassNotFoundException {
    log.info("----------------->>>>>>>开启日志<<<<<------------------------");
    LOCK.lock();
    try {
		AopContext.getCurrentAOP().sellProductZ();
    } finally {
        System.out.println(Thread.currentThread().getName() + ":释放锁");
        // 释放锁
        LOCK.unlock();
    }
}

需要开启一下,将当前对象保存到当前环境中来。

@Transactional
public void sellProductZ() {
    System.out.println(Thread.currentThread().getName() + ":抢到锁了,进入到方法中来");
    // 首先查询库存
    Product product = productMapper.selectById(1L);
    Integer productcount = product.getProductcount();
    System.out.println(Thread.currentThread().getName() + ":当前库存是:" + productcount);
    if (productcount > 0) {
        product.setProductcount(productcount - 1);
        // 更新操作
        productMapper.updateById(product);
        Buy buy = new Buy();
        buy.setProductname(product.getProductname());
        buy.setUsername(Thread.currentThread().getName());
        // 保存操作
        buyMapper.insert(buy);
        System.out.println(Thread.currentThread().getName() + ":减库存,创建订单完毕!");
    } else {
        System.out.println(Thread.currentThread().getName() + ":没有库存了");
    }
}

但是也可以有另外的方式来进行解决,开两个不同的数据库事务来进行处理。

当前没有遇到过这种情况,如果遇到了,那么可以来继续进行分析。

标签:事务,buy,currentThread,Thread,Spring,getName,product,传播,println
来源: https://www.cnblogs.com/likeguang/p/16686984.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有