我有以下弹簧配置。
<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”值保存在数据库中。嵌套事务行为是否正确?我如何实现这一目标?
答案 0 :(得分:3)
问题是您手动创建TestObj。您应该使用spring上下文(在上下文中将其声明为bean并在测试中声明自动装配)。
Spring会将此bean包装在代理中以使其成为事务性的。在您的情况下,它是一个没有事务行为的普通旧java对象。