Spring @Transactional并发
class MyService { public void a() { synchronized(somekey) { b(); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public void b() { ...do DB works... } }
class MyService { public void a() { synchronized(somekey) { b(); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public void b() { ...do DB works... } }
class MyService { public void a() { synchronized(somekey) { b(); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public void b() { ...do DB works... } }
我的目标是
- 1 – 拿到钥匙
- 2 – 开始交易
- 3 – 提交事务
- 4 – 释放钥匙
当我从外部调用a()方法时,事务不起作用。
有什么建议么 ?
谢谢。
除非你使用代码编织,否则这不起作用。
Spring处理事务的默认方式是通过AOP代理 。 对事务方法的调用如下:
caller --> ProxyClass.a() --> YourClass.a()
如果在同一个对象上调用另一个方法,则不会通过代理,因此没有事务行为。
caller --> ProxyClass.a() --> YourClass.a() --> YourClass.b()
如果您不想使用AspectJ,可以使用AopContext.currentProxy()
获取代理对象。
不是100%肯定。 我认为所有@Transactional调用必须在事务开始的同一个线程上完成。 我确信@Transactional不能跨线程工作 。 (我想通过设计)
我很好奇钥匙的性质。 为什么服务会产生它? 不会有替代设计将其放入数据库吗?
没有错误信息很难确切地说出错误。
如果你想在b()
调用b()
,并且想要使b()
事务,你必须将它放入单独的类中。
对Henning所说的方法调用b()是内部调用而不是事务代理。
整篇文章在这篇博文中有解释。