【发布时间】:2019-10-27 10:31:44
【问题描述】:
我知道使控制器具有事务性并不是最佳实践,但我想尝试here 讨论的解决方案
根据Spring MVC documentation 17.3.2:
在使用需要为控制器对象创建代理的功能(例如 @Transactional 方法)时,使用带注释的控制器类时会发生一个常见的陷阱。通常您会为控制器引入一个接口,以便使用 JDK 动态代理。要完成这项工作,您必须将@RequestMapping 注释以及任何其他类型和方法级别的注释(例如@ModelAttribute、@InitBinder)移动到接口以及映射机制只能“看到”由代理。
如果我“将所有方法注释移至其接口”,我应该能够使 RestController 方法具有事务性吗?
在这种假设下,我编写了以下代码,但仍然没有给我一个事务性的 doSth() 方法:
public interface SomeController{
@Transactional
@RequestMapping(...)
void doSth()
}
@RestController
public class SomeControllerImpl implements SomeController{
@Override
public void doSth(){...}
}
web.xml
<servlet>
<servlet-name>someServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>...</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>...</url-pattern>
</servlet-mapping>
context.spring.xml
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/project" resource-ref="true" />
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
有人可以帮助解释为什么这不起作用吗?有没有办法让 RestController 中的方法具有事务性?
【问题讨论】:
-
好奇:你为什么称你的控制器为
Service?是否应该命名为SomeWebController? -
该代码无法编译,因为
doSth在类中必须是public。 --- 无论如何,你怎么知道它没有给你一个事务性的doSth()方法?你没有具体说明你是怎么知道的,所以据我们所知,你错了,它确实使它成为事务性的。 -
嘿 Andreas,我在 SomeWebServiceImpl 中自动编写了一个 SessionFactory 并用它来 getCurrentSession().getTransaction() 并且没有事务
-
你配置了 TransactionManager bean 吗?
-
具体来说,我在 doSth() 中调用了 SomeService.transactionalMethod() (传播类型为Required)两次,发现这两个调用使用不同的事务,如果 doSth 则不会这样() 已经是事务性的
标签: java spring rest transactions