Spring的@Transactional不起作用。

4
我正在尝试使用带注释的TX Spring支持。
应用程序上下文XML:
<?xml ...>

    <tx:annotation-driven/>

    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
        ...
    </bean>

    <bean id="repository" class="Repository">
        <constructor-arg ref="dataSource"/>
    </bean>
</beans>

实际代码:
public class Repository {
    @Transactional
        public void save(Op op) {
            System.out.println("Transaction active:::: " + TransactionSynchronizationManager.isActualTransactionActive());

    ...
    }
}

呼叫代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/integration-context.xml"})
public class RepositoryTest {
    @Autowired
    private Repository repository;          

    @Test
    public void testRepositoryPersistence() {
        Op op = mock(Op.class);

        repository.save(op);
    }
}

这段文字的翻译是:“它会返回 FALSE。我做错了什么?”

你能展示一下你是如何调用 save 方法的吗? - geoand
这里的信息不足。你是如何解释 @Transactional 的?使用 Spring 代理吗?使用 Spring AOP 吗?还是使用某种编织方式?这个 bean 是否一定由 Spring 创建 - 即它在某个地方被自动装配了吗?另外,为什么要使用 XML? - Boris the Spider
你是如何加载XML文件的?又是如何调用保存方法的?这里提供的信息太少了。 - M. Deinum
扩展了我的问题。 - Denis Kulagin
你尝试过使用 <tx:annotation-driven proxy-target-class=true/> 吗? - geoand
1个回答

9
你应该在你的配置中添加这个。
<context:annotation-config/>

<tx:annotation-driven  transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
</bean>

在您的RepositoryClass上添加一个接口。
public class Repository implements IRepository{
    @Transactional
        public void save(Op op) {
            System.out.println("Transaction active:::: " + TransactionSynchronizationManager.isActualTransactionActive());

    ...
    }
}

在您的测试类中加入这个。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/integration-context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class RepositoryTest extends AbstractTransactionalJUnit4SpringContextTests{
    @Autowired
    private IRepository repository;          

    @Test
    public void testRepositoryPersistence() {
        Op op = mock(Op.class);

        repository.save(op);
    }
}

看看这个教程:点击这里

2
+1,因为这很可能是正确的。值得注意的是,如果OP正在使用编织(加载或编译时),那么“接口”并不是严格要求的。但这绝对是一个好习惯! - Boris the Spider
1
只有当您希望测试成为事务边界时,才需要扩展AbstractTransactionalJUnit4SpringContextTests。这并不是交易工作的必要条件。该设置基本上使得此服务上的@Transactional无用(除非它是REQUIRES_NEW或NEVER传播级别)。 - M. Deinum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接