@Transactional 4个使用心得小记

本文探讨了Spring的@Transactional注解如何影响多线程环境中的数据操作,包括线程阻塞、并发控制和数据一致性。通过实例演示了事务隔离级别对不同场景的影响,以及如何理解查询行为和数据同步问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1@Transactional 不能保证线程安全 但是 多线程执行同一个 @Transactional修饰的方法 如果一个线程 保存 数据但是未提交 会阻塞另个线程的数据 保存

  @Override
    @Transactional
    public   int testTransactional(String ip, String threadName)
    {

        DeviceInfo deviceInfo = deviceInfoMapper.selectdeviceInfoById(ip);
        DeviceInfo deviceInfo1 = new DeviceInfo();
        deviceInfo1.setIp(ip);

      int  isNat = deviceInfo.getIsNat().intValue();
        if(threadName.equals("a")){
            try {
                System.out.println(threadName+"threadsleep:"+2000l);
                Thread.sleep(2000l);
                System.out.println(threadName+"threadsleep:recovery");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }else {
            try {
                System.out.println(threadName+"threadsleep:"+5000l);
                Thread.sleep(5000l);
                System.out.println(threadName+"threadsleep:recovery");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int i = isNat+1;
        deviceInfo1.setIsNat(i);

        System.out.println(threadName+"isNat:"+isNat);

        int i1 = deviceInfoMapper.updatedeviceInfo(deviceInfo1);
        if(threadName.equals("a")){
            try {
                System.out.println(threadName+"threadsleep:"+10000l);
                Thread.sleep(10000l);
                System.out.println(threadName+"threadsleep:recovery");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        System.out.println(threadName+" wancheng:"+i1);
        return  1;

    }
 

    @PostConstruct()
    public void testT(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                eventLogsService.testTransactional("172.16.7.1","a");
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                eventLogsService.testTransactional("172.16.7.1","b");
            }
        }).start();
    }

说明: 启动两个线程去保存数据  a线 暂停2s b线程暂停5s 2后 a线程保存数据 并且a线程阻塞10s但是不提交  3s后 b线程恢复 保存并且提交 会发现 b线程的保存操作被阻断了(说明有表行锁)  等a线程 10s后恢复 提交数据后  b线程才能正常提交数据

2@Transactional 修饰的方法 同一线程下 两次查询可以查询自己 提交但是未保存的数据 但是另个线程是不能查询到未提交数据的

  @Override
    @Transactional
    public   int testTransactional(String ip, String threadName)
    {
        DeviceInfo deviceInfo = deviceInfoMapper.selectdeviceInfoById(ip);
        DeviceInfo deviceInfo1 = new DeviceInfo();
        deviceInfo1.setIp(ip);
        int  isNat = deviceInfo.getIsNat().intValue();
        System.out.println(threadName+"isNat:"+isNat);
        int i = isNat+1;
        deviceInfo1.setIsNat(i);
        if(threadName.equals("a")){
            try {
                int i1 = deviceInfoMapper.updatedeviceInfo(deviceInfo1);
                Thread.sleep(5000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        if(threadName.equals("b")){
            try {
                Thread.sleep(2000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        DeviceInfo deviceInfo2 = deviceInfoMapper.selectdeviceInfoById(ip);
        System.out.println(threadName+"isNatover:"+deviceInfo2.getIsNat());
        return  1;
    }

  @PostConstruct()
    public void testT(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                eventLogsService.testTransactional("172.16.7.1","a");
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                eventLogsService.testTransactional("172.16.7.1","b");
            }
        }).start();
    }

说明:启动两个线程 线程a线程b 

a b线程查询 数据库字段isNat 数据是13  b线程阻塞2s a线程 更新isNat  14保存但是不提交 然后a线程阻塞5s 3s后 b线程 恢复查询 a线程提交但是未保存的数据 结果还是13 a线程恢复读取自己 提交但是未保存的数据 是14  

3@Transactional如果 两个线程  一个线程删除另个线程保存未提交的数据会怎样

         应该是 不能删除发生阻塞 等提交以后再删除

4@Transactional 两个线程 如果修改保存一个线程删除提交的数据呢

    等通过于 修改 删除的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值