首先,准备service接口,两个
public interface AccountService { public void createAccount(Account account, int throwExpFlag) throws Exception; public void createAccountShell(Account account, int i) throws Exception; }
public interface RoleService { public void createAccountShell(Account account, int i) throws Exception; }
相关impl
@Service public class AccountServiceImpl implements AccountService { @Resource private AccountDAO accountDAO; @Override @Transactional public void createAccount(Account account, int throwExpFlag) throws Exception { accountDAO.save(account); RoleServiceImpl.throwExp(throwExpFlag); } @Override public void createAccountShell(Account account, int i) throws Exception { this.createAccount(account, i); } }
@Service public class RoleServiceImpl implements RoleService { @Autowired AccountService accountService; public static void throwExp(int throwExpFlag) throws Exception { if (throwExpFlag == 0) { throw new RuntimeException("<< rollback transaction >>"); } else if (throwExpFlag != 1) { throw new Exception("<< do not rollback transaction >>"); } } @Override public void createAccountShell(Account account, int i) throws Exception { accountService.createAccount(account, i); } }
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring/spring-dao.xml", "classpath:spring/spring-service.xml"}) public class ServiceTransactionTest extends TestCase { public static Account account; static { account = new Account(); account.setId(779); account.setUsername("779 USER"); account.setPassword("0123456"); } @Autowired AccountService accountService; @Autowired RoleService roleService; @Test public void test_1() throws Exception { this.accountService.createAccount(account, 0); } @Test public void test_2() throws Exception { this.accountService.createAccountShell(account, 0); } @Test public void test_3() throws Exception { roleService.createAccountShell(account, 0); } }
(一)对测试类的test_1方法进行单元测试时,由于AccountServiceImpl.createAccount方法显示配置了事务(@Transactional),所以spring正常接管事务。
(二)对测试类的test_2方法进行单元测试时,AccountServiceImpl.createAccountShell方法并没有显示配置事务,但其却调用了AccountServiceImpl.createAccount方法(已配事务)。然并卵,当抛出RuntimeException时,没有rollback,说明spring没有接管事务。(猜测原因:AccountServiceImpl.createAccountShell 被显示调用时,spring是知道的,但由于AccountServiceImpl.createAccountShell没有显示配置事务,spring并没有对此进行事务的管理,在AccountServiceImpl.createAccountShell内部虽然调用了配置了事务的createAccount方法,但spring并不知道或无法确定事务上下文,所以结果是并没有因为抛出的运行时异常而进行rollback)。
(三)测试test_3,虽然RoleServiceImpl.createAccountShell同样没有配置事务,但抛出RuntimeException时,spring接管了事务并rollback。(猜测原因:虽然RoleServiceImpl.createAccountShell没有配置事务,但其内部调用另一个service实例的方法,即AccountService.createAccount时,spring对此是获知的,又因为AccountServiceImpl.createAccount显示配置了事务,所以spring接管了事务)。
(四)如果在AccountServiceImpl.createAccountShell配置了事务,那么在执行test_2时,spring是可以接管事务的。