Spring 交易管理
Spring transaction management
我正在研究 spring4 mvc 以在我们的新 Web 应用程序中引入,目前我们正在使用 struts1.x 并希望使用新框架来支持 html5/ajax 请求,就像可能并希望使用 DI 的强大功能和 spring webflow 支持。
目前,在我们的 struts1.x 应用程序中,数据库事务管理是在我们的自定义 GenericAction 中完成的,它是 Action 的子class,在 GenericAction 中,我们从数据源获取连接并移交给子classes 然后引发任何异常然后捕获并回滚,否则提交使得数据库原子性(事务管理)在一个地方完成。所有模块操作 classes 都应该扩展 GenericAction,以便数据库连接可用并执行模块相关的东西,完成连接后将在 GenericAction 中回滚或提交,如上所述。
在 spring 中,事务的范围以 @Transactional 注释开始,然后以服务 Class 中的方法结束,因为服务 class 标记为 @Transactional。这对我来说不是可行的解决方案。在开始之前,我已经阅读了与 spring 交易相关的几份文件,以下是我的问题。
我正在使用 HibernateTransactionManager 作为事务管理器
如果是 Web 请求或任何 class(在单元测试的情况下),事务应该从拦截器开始。
如果是 Web 请求或任何 class 在单元测试的情况下,事务应以拦截器执行后结束。
如果出现任何异常,我们的 HandlerExceptionResolverImpl 处理程序将执行,然后连接应该回滚。
任何解决方法或最佳实践将不胜感激。
谢谢
多莱拉吉
在我看来,您可以通过遵循 Spring 在其 org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(Object, TransactionDefinition) 中所做的操作,以对当前应用程序进行最小的更改来实现此目的。详细来说,我认为像下面这样的东西应该有效:
- 在 GenericAction 上,从数据源获取连接(正如您已经完成的那样)
- 通过其持有者将连接与当前数据源绑定:
TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
- 最终,将事务提交为 org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DefaultTransactionStatus)。
无论如何,Spring 的 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/support/TransactionTemplate.html 可以帮助实现您想要的任何程序化交易场景。只需要确保正确的事务资源绑定到打开的事务。
希望对您有所帮助。
感谢您的回复。您的 post/suggestion 驱动器执行以下操作
我编写了一个名为 TxtManager 的拦截器,下面是执行事务管理的方法。
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception
{
Session session = sessionFactory.openSession();
SessionHolder hold = new SessionHolder(
session);
TransactionSynchronizationManager.bindResource(sessionFactory, hold);
// passing null would accept the default transaction definition.
status = transactionManager.getTransaction(null);
return true;
}
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception
{
Exception hanlderEx = (Exception) request
.getAttribute(HandlerExceptionResolverImpl.EXCEPTION_KEY);
if (hanlderEx != null)
{
transactionManager.rollback(status);
}
else
{
transactionManager.commit(status);
}
}
在负责异常处理的HandlerExceptionResolverImplclass中,在请求中放入一个异常对象,在拦截器的afterCompletion方法中读取相同的异常回滚或提交。
在(preHandler 和 afterCompletion)之间,我们将使用标准实践来执行与模块相关的内容,包括任何其他拦截。可能不支持单元测试,我会检查其他替代单元测试。
最后我们能够根据您的建议模拟现有的框架工作谢谢
如有任何改进建议,我们将不胜感激!!..
谢谢
多莱拉吉
我正在研究 spring4 mvc 以在我们的新 Web 应用程序中引入,目前我们正在使用 struts1.x 并希望使用新框架来支持 html5/ajax 请求,就像可能并希望使用 DI 的强大功能和 spring webflow 支持。
目前,在我们的 struts1.x 应用程序中,数据库事务管理是在我们的自定义 GenericAction 中完成的,它是 Action 的子class,在 GenericAction 中,我们从数据源获取连接并移交给子classes 然后引发任何异常然后捕获并回滚,否则提交使得数据库原子性(事务管理)在一个地方完成。所有模块操作 classes 都应该扩展 GenericAction,以便数据库连接可用并执行模块相关的东西,完成连接后将在 GenericAction 中回滚或提交,如上所述。
在 spring 中,事务的范围以 @Transactional 注释开始,然后以服务 Class 中的方法结束,因为服务 class 标记为 @Transactional。这对我来说不是可行的解决方案。在开始之前,我已经阅读了与 spring 交易相关的几份文件,以下是我的问题。 我正在使用 HibernateTransactionManager 作为事务管理器
如果是 Web 请求或任何 class(在单元测试的情况下),事务应该从拦截器开始。
如果是 Web 请求或任何 class 在单元测试的情况下,事务应以拦截器执行后结束。
如果出现任何异常,我们的 HandlerExceptionResolverImpl 处理程序将执行,然后连接应该回滚。
任何解决方法或最佳实践将不胜感激。
谢谢 多莱拉吉
在我看来,您可以通过遵循 Spring 在其 org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(Object, TransactionDefinition) 中所做的操作,以对当前应用程序进行最小的更改来实现此目的。详细来说,我认为像下面这样的东西应该有效:
- 在 GenericAction 上,从数据源获取连接(正如您已经完成的那样)
- 通过其持有者将连接与当前数据源绑定: TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
- 最终,将事务提交为 org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DefaultTransactionStatus)。
无论如何,Spring 的 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/support/TransactionTemplate.html 可以帮助实现您想要的任何程序化交易场景。只需要确保正确的事务资源绑定到打开的事务。
希望对您有所帮助。
感谢您的回复。您的 post/suggestion 驱动器执行以下操作
我编写了一个名为 TxtManager 的拦截器,下面是执行事务管理的方法。
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception
{
Session session = sessionFactory.openSession();
SessionHolder hold = new SessionHolder(
session);
TransactionSynchronizationManager.bindResource(sessionFactory, hold);
// passing null would accept the default transaction definition.
status = transactionManager.getTransaction(null);
return true;
}
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception
{
Exception hanlderEx = (Exception) request
.getAttribute(HandlerExceptionResolverImpl.EXCEPTION_KEY);
if (hanlderEx != null)
{
transactionManager.rollback(status);
}
else
{
transactionManager.commit(status);
}
}
在负责异常处理的HandlerExceptionResolverImplclass中,在请求中放入一个异常对象,在拦截器的afterCompletion方法中读取相同的异常回滚或提交。
在(preHandler 和 afterCompletion)之间,我们将使用标准实践来执行与模块相关的内容,包括任何其他拦截。可能不支持单元测试,我会检查其他替代单元测试。
最后我们能够根据您的建议模拟现有的框架工作谢谢
如有任何改进建议,我们将不胜感激!!..
谢谢 多莱拉吉