gpt4 book ai didi

java - 如何不回滚以前的方法持久化数据?

转载 作者:行者123 更新时间:2023-11-30 09:01:15 25 4
gpt4 key购买 nike

我的 DAO 接口(interface)很简单:

import org.springframework.transaction.annotation.Transactional;

@Component
@Transactional
public interface TTestDao {

@Transactional()
public void first();

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void second() ;

}

广告植入方法:

@Override
public void first() {
entityManager.persist(new TableTest1().setName("data1"));
this.second();
}

public void second() {
entityManager.persist(new TableTest1().setName("data2"));
throw new RuntimeException(); // it roll backs data2 and data1
}

第一个方法调用第二个方法。第二种方法出错。

此刻,如果我调用first(),所有持久化的信息都将被回滚。但是为什么会这样呢? second() 方法在一个新事务中,我需要将第一个方法的数据保存在数据库中。

换句话说,我需要一直持久化第一个方法的数据,而只回滚第二个方法的数据。我想一直写data1。

我有什么问题吗?

我在SPRING中有这样一个数据库配置:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="oracle.jdbc.driver.OracleDriver" p:url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
p:username="dev" p:password="****" >
</bean>


<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>

<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

<context:component-scan base-package="ge.ddrc.transport.persistance.entity">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>


<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />

我的应用程序在 tomcat 中运行(如果它有意义的话)

最佳答案

@StijnGeukens 很接近。 Spring 实际上确实使用代理来处理事务,并且通过 default从一个事务方法调用另一个事务方法不会导致创建新事务。但是,在这种情况下,传播被明确设置为显式 require a new正在创建的交易。应该创建 2 个事务:

T1: create
T2: create
Exception occurs here
T2: commit
T1: commit

如您所见,异常发生在任一事务到达其提交点之前。由于它未在 First 中处理,因此执行永远不会到达 T1 的提交点。这将导致顶层事务被回滚。

但是,您可以在 First 中处理异常,但它仍然无法正常工作。来 self 上面链接的文档:

Note: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available it to it (which is server-specific in standard J2EE).

所以您的 propagation=REQUIRES_NEW 可能实际上没有按照它所说的去做,因为它不喜欢您的 TransactionManager。欢迎来到 Spring 。

更新来自JpaTransactionManager文档:

On JDBC 3.0, this transaction manager supports nested transactions via JDBC 3.0 Savepoints. The AbstractPlatformTransactionManager.setNestedTransactionAllowed(boolean)
"nestedTransactionAllowed"
flag defaults to "false", though, as nested transactions will just apply to the JDBC Connection, not to the JPA EntityManager and its cached objects. You can manually set the flag to "true" if you want to use nested transactions for JDBC access code which participates in JPA transactions (provided that your JDBC driver supports Savepoints). Note that JPA itself does not support nested transactions! Hence, do not expect JPA access code to semantically participate in a nested transaction.

这非常令人困惑,但我认为它的意思是,如果您设置提到的标志,您将能够使用嵌套事务,使用 JDBC 3.0 的功能实现。因此,请确保您的驱动程序符合该规范。

关于java - 如何不回滚以前的方法持久化数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26467006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com