@Transactional注解问题

k851590063 2017-11-02 10:19:35
在某个service实现类中,save方法(没有@Transactional标记)中调用了私有方法b,私有方法用@Transactional标记了,当我在controller层中调用save方法时,控制台报错了,大概是什么事务已经提交的什么错,但是我在save方法底部new了一个线程,把私有方法b放到线程中,然后在调用save方法,就不会报错,请问下大神这是为什么?为什么放到线程中就不报错
...全文
470 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
maradona1984 2017-11-06
  • 打赏
  • 举报
回复
引用 7 楼 k851590063 的回复:
[quote=引用 6 楼 maradona1984 的回复:] spring的事务是通过AOP,AOP是动态代理实现,A方法没有注解,相当于没有事务方面的代理增强,然后调用有 @Transactional 的B方法,但代理模式是基于类的,所以A调用B方法也是没有代理增强,具体报错的原因估计也是如此,但为啥你开一个线程为啥没报错,那得看你代码怎么写的了

class proxy{
       A a;
       public void save(){
             a.save();
       }
       public void b(){
            //开启事务
            a.b();
            //提交事务
       }
}
Class A{
       public void save(){
               //这样调用就没有代理类的开启事务和增强事务的过程了
               b();
       }
       @Transactional
      public void b(){
             //数据库操作
      }
}

class C{
Proxy p;
public void start(){
      p.save();
}
}
public class xxxServiceImpl{ public void save() { save(); Thread thread = new Thread() { @Override public void run() { try { sendMsg(); } catch (Exception e) { logger.error("发送短信异常", e); } } }; thread.start(); } @Transactional private void sendNotice() { // 数据库操作 } } 代码大概是这么写的,如果不new线程,把sendMsg方法放到save()方法后执行就会报错,报错的内容大概是事务已经提交什么的[/quote] 原理我只能跟你这么讲,但实现的细节就很繁琐了,所以避免这种用法就行了 aop很多实现应该都是基于ThreadLocal来存储一些额外的数据的,或许开启新的线程就避开了原ThreadLocal了 当然这只是猜测罢了,还有建议把具体错误贴出来
k851590063 2017-11-05
  • 打赏
  • 举报
回复
引用 4 楼 wcl1598593 的回复:
[quote=引用 3 楼 k851590063 的回复:] 为什么不new线程就会报表,一个事务会报错? [quote=引用 1 楼 wcl1598593 的回复:] ----大概是什么事务已经提交的什么错,但是我在save方法底部new了一个线程,把私有方法b放到线程中,然后在调用save方法,就不会报错 new 了线程后,事务就已经脱离主线程的管控了(不是一个事务了),所以就不会报错了
[/quote] 报的什么错?[/quote]大概意思是事务已经提交什么的
k851590063 2017-11-05
  • 打赏
  • 举报
回复
引用 6 楼 maradona1984 的回复:
spring的事务是通过AOP,AOP是动态代理实现,A方法没有注解,相当于没有事务方面的代理增强,然后调用有 @Transactional 的B方法,但代理模式是基于类的,所以A调用B方法也是没有代理增强,具体报错的原因估计也是如此,但为啥你开一个线程为啥没报错,那得看你代码怎么写的了

class proxy{
       A a;
       public void save(){
             a.save();
       }
       public void b(){
            //开启事务
            a.b();
            //提交事务
       }
}
Class A{
       public void save(){
               //这样调用就没有代理类的开启事务和增强事务的过程了
               b();
       }
       @Transactional
      public void b(){
             //数据库操作
      }
}

class C{
Proxy p;
public void start(){
      p.save();
}
}
public class xxxServiceImpl{ public void save() { save(); Thread thread = new Thread() { @Override public void run() { try { sendMsg(); } catch (Exception e) { logger.error("发送短信异常", e); } } }; thread.start(); } @Transactional private void sendNotice() { // 数据库操作 } } 代码大概是这么写的,如果不new线程,把sendMsg方法放到save()方法后执行就会报错,报错的内容大概是事务已经提交什么的
北辰 2017-11-03
  • 打赏
  • 举报
回复
引用 3 楼 k851590063 的回复:
为什么不new线程就会报表,一个事务会报错? [quote=引用 1 楼 wcl1598593 的回复:] ----大概是什么事务已经提交的什么错,但是我在save方法底部new了一个线程,把私有方法b放到线程中,然后在调用save方法,就不会报错 new 了线程后,事务就已经脱离主线程的管控了(不是一个事务了),所以就不会报错了
[/quote] 报的什么错?
k851590063 2017-11-03
  • 打赏
  • 举报
回复
为什么不new线程就会报表,一个事务会报错?
引用 1 楼 wcl1598593 的回复:
----大概是什么事务已经提交的什么错,但是我在save方法底部new了一个线程,把私有方法b放到线程中,然后在调用save方法,就不会报错 new 了线程后,事务就已经脱离主线程的管控了(不是一个事务了),所以就不会报错了
k851590063 2017-11-03
  • 打赏
  • 举报
回复
为什么不new线程就会报表,一个事务会报错?
北辰 2017-11-03
  • 打赏
  • 举报
回复
----大概是什么事务已经提交的什么错,但是我在save方法底部new了一个线程,把私有方法b放到线程中,然后在调用save方法,就不会报错 new 了线程后,事务就已经脱离主线程的管控了(不是一个事务了),所以就不会报错了
maradona1984 2017-11-03
  • 打赏
  • 举报
回复
spring的事务是通过AOP,AOP是动态代理实现,A方法没有注解,相当于没有事务方面的代理增强,然后调用有 @Transactional 的B方法,但代理模式是基于类的,所以A调用B方法也是没有代理增强,具体报错的原因估计也是如此,但为啥你开一个线程为啥没报错,那得看你代码怎么写的了

class proxy{
       A a;
       public void save(){
             a.save();
       }
       public void b(){
            //开启事务
            a.b();
            //提交事务
       }
}
Class A{
       public void save(){
               //这样调用就没有代理类的开启事务和增强事务的过程了
               b();
       }
       @Transactional
      public void b(){
             //数据库操作
      }
}

class C{
Proxy p;
public void start(){
      p.save();
}
}
宝宝很6 2017-11-03
  • 打赏
  • 举报
回复
感觉像是什么资源有冲突

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧