2

请参阅我的以下代码片段。

@Transactional
public void saveMembersService(List<Member> list1, List<Member> list2)
{
    saveMembersDAO(list1); // does not perform commit. Why?
    saveMembersDAO(list2); // does not perform commit. Why?
} // does perform commit only here!

@PersistenceContext
private EntityManager em;

@Transactional
public void saveMembersDAO(List<Member> members)
    throws HibernateException
{
    Iterator<Member> it = members.iterator();
    while (it.hasNext())
    {
        Member wsBean = it.next();
        em.persist(wsBean); // overall commit will be made after method exit
    }
}

我使用 MySQL 作为数据库。在执行上述方法后,我会查看 MySql 日志。但是在saveMembersService方法执行后我只能看到单个提交。我希望看到每个事务方法调用的两个提交。我哪里错了?

更新 1:对不起,我忘记将 @Transactional 添加到我的服务方法中。现在修好了

更新 2:我已经检查了 DAO 的Propagation.REQUIRES_NEW属性 - 结果是相同的(在服务方法中使用和不使用 @Transactional)

4

1 回答 1

3

当使用@Transactional 时,Spring 会在您的类周围创建一个代理,并且内部调用的方法不会传入代理。

你必须这样做。您可以通过在 Spring 上下文中创建 TransactionTemplate 来清理它。

@Autowired
private PlatformTransactionManager transactionManager;

public void saveMembersDAO(List<Member> members)
    throws HibernateException
{
    TransactionDefinition txDef = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    TransactionTemplate txTemplate = new TransactionTemplate(transactionManager, trDef)

    txTemplate.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            Iterator<Member> it = members.iterator();
            while (it.hasNext())
            {
                Member wsBean = it.next();
                em.persist(wsBean);
            }
        }
    });
}

如果您正在使用 AspectJ 并且想要进行 2 次提交。您必须在 saveMembersDAO 上使用 @Transactional(propagation = Propagation.REQUIRES_NEW)

于 2012-10-16T19:05:10.567 回答