首先,准備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是可以接管事務的。