spring交易传播,REQUIRED,REQUIRES_NEW


问题内容

在下面的代码方法doService1()更新正确的SQL,但doService2()SQL有一些问题,但是当我打电话doService()它必须提交doService1()更新到数据库,即使doService2()有sql exception,因为doService2() 有一个REQUIRES_NEW Propagation类型,但是当我尼姑此doService1()更新不承诺DB ..

@Service public class DbClass {

      static Logger log = Logger.getLogger(
              DbClass.class.getName());

@Autowired
private DataSource dataSource;

@Transactional(propagation=Propagation.REQUIRED)
public void doService(){
    doService1();
    doService2();
}

@Transactional(propagation=Propagation.REQUIRED)
public void doService1(){
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "  update BATCHJOBSTATUS set PROCESSINGDATE = '20130322'  " ;
    int rowCount1 =  jdbcTemplate.update(sql);
    System.out.println(" rowCount1 >" + rowCount1);
}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void doService2(){
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "  update aa set a_name = 'hhh' where a_id = 4 and " ;
    int rowCount1 =  jdbcTemplate.update(sql);
    System.out.println(" rowCount2 >" + rowCount1);
}   
}

也可以按照以下方式进行你们的建议测试,但仍然面临相同的问题。在这里,我doService2()在一个单独的班级中,尽管仍然有与上述相同的问题

@Service
public class DbClass {

  static Logger log = Logger.getLogger(
          DbClass.class.getName());

@Autowired
private DataSource dataSource;

@Autowired
private DbClass2 dbClass2;

@Transactional
public void doService(){
    doService1();
    dbClass2.doService2();
}

@Transactional(propagation=Propagation.REQUIRED )
public void doService1(){
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "  update BATCHJOBSTATUS set PROCESSINGDATE = '20130322'  " ;
    int rowCount1 =  jdbcTemplate.update(sql);
    System.out.println(" rowCount1 >" + rowCount1);

    }


}


@Service
public class DbClass2 {

问题答案:

我之前有同样的问题,在这里已解决:@Transactional(propagation = Propagation.REQUIRES_NEW)奇怪的行为

使用默认设置,当您doService2()从同一类调用时,不会创建任何新的事务代理,因此您的注释不是用户。

为了避免这个问题,您可以放入doService2()另一个类或使用aspectJ进行事务处理,方法是这样声明:<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

最佳解决方案将取决于您的应用程序。(这里的第二个似乎更合适)