0

我尝试为@Transactional.

@ContextConfiguration(locations = {"classpath:/META-INF/spring/app-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class TransactionalAnnotationTest {
    public static final BigDecimal PROD_ID = new BigDecimal(1234);

    @PersistenceContext
    HibernateEntityManager em;


    @Test
    public final void testTransactionIsolation() {
        String original = em.find(ProductImpl.class, PROD_ID).getDescription();
        // original = "Foo"
        updateTx(original);
    }

    @Transactional
    public final void updateTx(String original) {
        ProductImpl product = em.find(ProductImpl.class, PROD_ID);
        product.setDescription("Bar");
        whatIsInDB(original);
    }

    private void whatIsInDB(String original) {
        String sameTxDescription = em.find(ProductImpl.class, PROD_ID).getDescription();
        assert !sameTxDescription.equals(original);
    }
}

它失败了!第二个em.find不应该返回带有“Bar”的产品吗?

4

2 回答 2

0

设置“描述”字段后尝试显式刷新上下文

product.setDescription("Bar");
em.flush();
whatIsInDB(original);

于 2013-08-22T15:23:28.817 回答
-1

嗯,我得到它的工作。

  1. 测试交易:em.flush()我只需要一个简单的东西(感谢@TaoufikMohdit 的想法)。如果没有交易,flush()抛出一个TransactionRequiredException
  2. @Transactional仅适用于 Spring-Managed-Beans。所以我创建了一个服务:

    @Service
    public class BasicTransactionalService {
      @PersistenceContext
      HibernateEntityManager em;
    
      @Transactional
      public void testFlushInTransactional() {
        em.flush();
      }
    
      @Deprecated
      public void testFlushOutsideTransactional() {
        em.flush();
      }
    
      @Transactional
      public void testFlushSubroutineTransactional() {
        testFlushOutsideTransactional();
      }
    }
    
  3. 我将测试更改为:

    @Autowired
    BasicTransactionalService bean;
    
    @Test
    public void testTransactionIsolation() {
      bean.testFlushInTransactional();
    }
    
    @Test(expected = TransactionRequiredException.class)
    @SuppressWarnings("deprecation")
    public void testThrowsTransactionRequiredException() {
      bean.testFlushOutsideTransactional();
    }
    
    @Test
    public void testTransactionalSubroutine(){
      bean.testFlushSubroutineTransactional();
    }
    

现在它工作正常。

顺便说一句,这是我的app-config.xml

<beans>
  <bean class="BasicTransactionalService" />
  <bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />
  <bean class="org.springframework.orm.jpa.JpaTransactionManager" />
  <tx:annotation-driven />
<beans>
于 2013-08-23T11:07:20.693 回答