Spring @Transactional在每个服务方法结束时提交

Sas*_*aXP 0 java spring jdbc vaadin spring-transactions

我在Vaadin,Spring项目中配置了一个通常的声明式事务管理.我已经<tx:annotation-driven transaction-manager="transactionManager" />在我的root-context.xml中添加了pom中所有其他所需的maven依赖项.我的服务方法@Transactional使用默认传播进行注释.

我想从UI方面的方法调用两个服务方法,期望这两个服务方法在单个事务中作为默认传播进行分区PROPAGATION_REQUIRED.但是这两种方法都是独立于db的.这意味着如果第二种方法失败,则第一种方法无论如何都要提交给数据库.我没有使用过try{}catch{{块,所以任何RuntimeException都会被冒泡.

弹簧记录附有.删除一些行以减少#of行

[qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/getTransaction Creating new transaction with name [...UserServiceImpl.turnOnPwdResetFlag]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/doBegin Switching JDBC Connection [com.jolbox.bonecp.ConnectionHandle@42398a05] to manual commit [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/handleExistingTransaction Participating in existing transaction [qtp187048467-48] DEBUG o.s.jdbc.core.JdbcTemplate/doInStatement SQL update affected 1 rows [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/processCommit Initiating transaction commit [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/doCommit Committing JDBC transaction on Connection [com.jolbox.bonecp.ConnectionHandle@42398a05] [qtp187048467-48] DEBUG o.s.jdbc.datasource.DataSourceUtils/doReleaseConnection Returning JDBC Connection to DataSource ` ` [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/getTransaction Creating new transaction with name [...UserServiceImpl.turnOffPwdResetFlag]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT;  [qtp187048467-48] DEBUG o.s.j.d.DataSourceTransactionManager/handleExistingTransaction Participating in existing transaction [qtp187048467-48] DEBUG o.s.jdbc.datasource.DataSourceUtils/doReleaseConnection Returning JDBC Connection to DataSource 
Run Code Online (Sandbox Code Playgroud)

dun*_*nni 6

如果要为两个方法调用都有一个事务,则必须确保调用这两个方法的方法也具有事务注释,如下例所示:

@Transactional
public void callingMethod() {
    method1();
    method2();
}

@Transactional
public void method1() {
}

@Transactional
public void method2() {
}
Run Code Online (Sandbox Code Playgroud)

  • 另一种方法是在您的服务层中创建一个方法,该方法调用您的其他两个方法并使用 Transactional 注释该新方法。 (2认同)

Sas*_*aXP 3

在Spring事务内部的帮助下,在视图过滤器中打开会话我想出了一个解决方案。

根据第一个链接,在 Spring MVC 上下文中,事务在控制器上下文中开始,@Transactional然后服务层中的方法参与、创建或在现有事务之上创建另一个适当的事务。但如果 UI 层不是 Spring MVC,则不会发生这种情况。

Spring交易流程

如该Spring 事务图像所示,事务顾问负责决定是提交事务还是标记回滚。因此,如果我们只是让服务方法代理创建一个事先不存在的事务,那么在该代理方法结束时,顾问会决定提交该事务。为了克服这个问题,我们必须在两个服务方法调用之前创建一个事务,因此这两个方法将加入事务而不是自行提交。

Hibernate上下文中,Spring MVC 支持 OpenSessionInView,它为每个请求创建一个事务。我所做的是创建一个类似的 servlet 过滤器,以在请求开始时创建事务并在过滤器链末尾提交。这在 Vaadin、Spring 和 JDBC 环境中完美运行。如果您非常担心每个 HTTP 请求都会获取 Spring 事务并因此获取数据库连接,请尝试使用LazyConnectionDataSourceProxy.

请参阅此处的解决方案:我想...使用 JDBC、Spring 事务和@Transactional