@Transcational 失效場景--轉載
第一種
Transcation注解用在非public方法上時,注解将會失效
比如@Transcation修飾一個default通路符的方法
@Component
public class TestServiceImpl {
@Resource
TestMapper testMapper;
@Transactional
void insertTestWrongModifier() {
int re = testMapper.insert(new Test(10,20,30));
if (re > 0) {
throw new NeedToInterceptException("need intercept");
}
testMapper.insert(new Test(210,20,30));
}
}
測試用例
@Component
public class InvokcationService {
@Resource
private TestServiceImpl testService;
public void invokeInsertTestWrongModifier(){
//調用@Transactional标注的預設通路符方法
testService.insertTestWrongModifier();
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Resource
InvokcationService invokcationService;
@Test
public void testInvoke(){
invokcationService.invokeInsertTestWrongModifier();
}
}
問題分析
以上的通路方式,導緻事務沒開啟,此時如果出現異常也不會復原,如果将事務方法修改為public,事務就會正常開啟
第二種
本類内部方法标注@transcation,這種情況下事務也不會生效
@Component
public class TestServiceImpl implements TestService {
@Resource
TestMapper testMapper;
@Transactional
public void insertTestInnerInvoke() {
//正常public修飾符的事務方法
int re = testMapper.insert(new Test(10,20,30));
if (re > 0) {
throw new NeedToInterceptException("need intercept");
}
testMapper.insert(new Test(210,20,30));
}
public void testInnerInvoke(){
//類内部調用@Transactional标注的方法。
insertTestInnerInvoke();
}
}
測試案例
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Resource
TestServiceImpl testService;
/**
* 測試内部調用@Transactional标注方法
*/
@Test
public void testInnerInvoke(){
//測試外部調用事務方法是否正常
//testService.insertTestInnerInvoke();
//測試内部調用事務方法是否正常
testService.testInnerInvoke();
}
}
上述情況使用測試代碼,事務不會開啟,如果用外部方法調用則會開啟事務
第三種
事務方法内部捕獲異常,沒有抛出異常,導緻事務不會生效
@Component
public class TestServiceImpl implements TestService {
@Resource
TestMapper testMapper;
@Transactional
public void insertTestCatchException() {
try {
int re = testMapper.insert(new Test(10,20,30));
if (re > 0) {
//運作期間抛異常
throw new NeedToInterceptException("need intercept");
}
testMapper.insert(new Test(210,20,30));
}catch (Exception e){
System.out.println("i catch exception");
}
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Resource
TestServiceImpl testService;
@Test
public void testCatchException(){
testService.insertTestCatchException();
}
}
異常被捕獲了,是以事務未生效
不會,我可以學;落後,我可以追趕;跌倒,我可以站起來!