有没有办法用 SpringMVC 设置 MyBatis 来为整个 http 请求设置一个事务?通常OpenSessionInViewFilter
在 MyBatis 中是否有类似 Hibernate 的东西,或者我应该编写自己的过滤器来实现这种行为?
4 回答
您对“会话”和“交易”的概念感到困惑。OSIV 打开会话,在一个会话中,多个事务可能共存。通常,您应该@Transactional
根据您的业务需求为控制器使用的服务添加属性。
此外,对所有事物的一项大交易是一种反模式。理想情况下是对用户的操作进行读写事务,然后另一个只读事务是为用户构建响应。它节省了资源,因为用于插入/更新的数据库锁被提前释放。
你可以让 Spring 来处理你的事务。
看看文档。我很容易。您只需要在需要它的方法中配置和添加@Transactional 注释。
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html
如果您确实需要将单个事务绑定到特定请求,您可以考虑TransactionTemplate
在您的Filter
. 我不认为你可以使用@Transactional
onFilter
除非它是由 Spring 管理的(例如:FilterChain
像 Spring Security's Filters.
这是你可以做的TransactionTemplate
public class TransactionalFilter implements Filter {
private TransactionTemplate transactionTemplate;
public void destroy() {
}
public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws ServletException, IOException {
transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
try {
chain.doFilter(req, resp);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
return null;
}
});
}
public void init(FilterConfig config) throws ServletException {
transactionTemplate = new TransactionTemplate(WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext()).getBean(PlatformTransactionManager.class));
}
}
我的建议是阅读以下帮助文档: http ://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/transaction.html
由于您没有完全控制 spring-mvc 框架的每个部分,我建议在 spring-mvc 的基类上使用 aop 切入点来启动事务(在每个请求上执行的方法。)你可以找到这个10.5.2 节中的方法。只要确保你切入点的类是由spring初始化的,否则它将不起作用。