1.@Transactional事務不生效的原因:
Spring事務是通過AOP實現的,所以擁有事務功能的是,接口的代理類,而非接口本身。這樣在調用@Transactional標注的方法時,要區分調用方法的入口是,代理類,還是,非代理類(如接口實現類自身)
如下:
@Service("tranService")
public class TranServiceImpl implements TranService{
@Autowired
private TransMapper transMapper;
@Transactional
public void test1(Long code){
transMapper.test1Insert(code);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void test2(String id){
transMapper.test2Insert(id);
int i = 1/0;
}
@Transactional
public void test3(Long code, String id){
test1(code);
test2(id);
}
}
//模擬調用Spring事務的方法
@Component("demo")
public class Demo {
private static Long code = 1L;
private static String id = "2";
@Autowired
private TranService tranService;//代理類
public void doDemo1(){
tranService.test1(code);//事務有效
}
public void doDemo2(){
tranService.test2(id);//事務有效
}
public void doDemo3(){
tranService.test3(code, id);//調用方法中只有test3一個事務,1、2屬於自調用,沒有事務切面
}
@Transactional
public void doDemo4(){//共有三個事務,doDemo4、test1、test2,由於事務傳播行為的設置,test1的事務,會合並到doDemo事務中;test2的事務是獨立的,test2的回滾,不會影響doDemo4的事務;
tranService.test1(code);
tranService.test2(id);
}
}
2.spring 事務特性
事務的隔離級別:是指若干個並發的事務之間的隔離程度
1. @Transactional(isolation = Isolation.READ_UNCOMMITTED):讀取未提交數據(會出現臟讀, 不可重復讀) 基本不使用
2. @Transactional(isolation = Isolation.READ_COMMITTED):讀取已提交數據(會出現不可重復讀和幻讀)
3. @Transactional(isolation = Isolation.REPEATABLE_READ):可重復讀(會出現幻讀)
4. @Transactional(isolation = Isolation.SERIALIZABLE):串行化
事務傳播行為:如果在開始當前事務之前,一個事務上下文已經存在,此時有若干選項可以指定一個事務性方法的執行行為
1. TransactionDefinition.PROPAGATION_REQUIRED: 如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。這是默認值。
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創建一個新的事務,如果當前存在事務,則把當前事務掛起。
3. TransactionDefinition.PROPAGATION_SUPPORTS: 如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務方式運行,如果當前存在事務,則把當前事務掛起。
5. TransactionDefinition.PROPAGATION_NEVER: 以非事務方式運行,如果當前存在事務,則拋出異常。
6. TransactionDefinition.PROPAGATION_MANDATORY: 如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
7. TransactionDefinition.PROPAGATION_NESTED: 如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行; 如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。