【问题标题】:Spring JpaTransactionManager with Nested transactions带有嵌套事务的 Spring JpaTransactionManager
【发布时间】:2014-12-10 07:09:13
【问题描述】:

我有以下弹簧配置。

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

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



<bean id='entityManagerFactory'
    class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'>
    <property name="persistenceUnitName" value="test" />
    <property name='dataSource' ref='dataSource' />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
             <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
        </bean>
    </property>
</bean>


<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/testdb" />
  <property name="username" value="test" />
  <property name="password" value="test" />
</bean>

我已经创建了以下实体。

@Entity(name="testtable")
public class Testtable implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(unique=true, nullable=false)
private int testid;

@Column(length=10)
private String description;

public Testtable() {
}

public int getTestid() {
    return this.testid;
}

public void setTestid(int testid) {
    this.testid = testid;
}

public String getDescription() {
    return this.description;
}

public void setDescription(String description) {
    this.description = description;
}

}

现在我想用这个设置测试嵌套事务的行为。所以我创建了以下测试类。

@TransactionConfiguration(defaultRollback=false)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:context-test.xml")
public class TableTest {

@Autowired
private TesttableRepository testtableRepository;

@Test
@Transactional
public void testMethod()
{
    Testtable entry = new Testtable();
    entry.setDescription("ABC");
    entry = testtableRepository.save(entry);
    TestObj t = new TestObj(testtableRepository);

    t.testNestedTransactional();


entry.setDescription("ABCEE");
 testtableRepository.save(entry);
assertNotNull(entry.getTestid());
}


}

public class TestObj {

public TestObj(TesttableRepository testtableRepository){
    this.testtableRepository = testtableRepository;
}

private TesttableRepository testtableRepository;

@Transactional(propagation=Propagation.NESTED )
public void testNestedTransactional(){
    Testtable entry1 = new Testtable();

        entry1.setDescription("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
         testtableRepository.save(entry1);

}

}

TestObj.java 中的 testNestedTransactional() 方法应该因为违反数据库约束而失败(字段描述的最大长度为 10)。即使此方法失败,我也希望将“ABCEE”值保存在数据库中。这对嵌套事务行为是否正确?我怎样才能实现这个目标?

【问题讨论】:

  • 首先,您的测试存在缺陷,因为您自己构建了TestObj,而不是使用弹簧托管实例。我也相信你对嵌套事务的理解是有缺陷的。我建议你为此做一些学习。我猜你只是想要一个新的交易而不是嵌套的交易。

标签: java spring hibernate transactions


【解决方案1】:

问题是您手动创建TestObj。您应该使用 Spring 上下文(在上下文中将其声明为 bean 并在测试中自动装配)。

Spring 会将这个 bean 包装在一个代理中以使其具有事务性。在您的情况下,它是一个普通的旧 Java 对象,没有事务行为。

【讨论】:

  • 是的,我已将 TestObj 设为 bean。但我仍然有同样的问题
  • @user1516815 日志中有异常吗?使用嵌套事务假定使用保存点。实际上,我不确定它在 spring/hibernate 中是否有足够的支持。如果您只需要问题中描述的行为,请传播内部方法 REQUIRES_NEW。如果您想了解 NESTED 的工作原理,请尝试使用低级 JDBC 保存点。
  • jpaDialect 支持 JDBC 保存点的实现是什么?谁能建议?
  • 我将 org.hibernate.dialect.MySQLInnoDBDialect 与 Mysql InnoDb 一起使用。现在我收到错误消息“JpaDialect 不支持保存点 - 检查您的 JPA 提供商的功能”
  • 您能否更新问题(代码)以提供更具体的信息?
猜你喜欢
  • 2016-09-10
  • 1970-01-01
  • 2017-05-30
  • 2019-07-12
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
相关资源
最近更新 更多