在同一個類中,一個方法調用另一個有註解(好比@Async,@Transational)的方法,註解是不會生效的。java
好比,下面代碼例子中,有兩方法,一個有@Transational註解,一個沒有。若是調用了有註解的addPerson()方法,會啓動一個Transaction;若是調用updatePersonByPhoneNo(),由於它內部調用了有註解的addPerson(),若是你覺得系統也會爲它啓動一個Transaction,那就錯了,其實是沒有的。spring
@Service public class PersonServiceImpl implements PersonService { @Autowired PersonDao personDao; @Override @Transactional public boolean addPerson(Person person) { boolean result = personDao.insertPerson(person)>0 ? true : false; return result; } @Override //@Transactional public boolean updatePersonByPhoneNo(Person person) { boolean result = personDao.updatePersonByPhoneNo(person)>0 ? true : false; addPerson(person); //測試同一個類中@Transactional是否起做用 return result; } }
如何查看是否啓動了Transaction?
設置log leve爲debug,能夠查看是否有下面這個log,判斷是否啓動了Transaction:
DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name...ide
一樣地,@Async等其餘註解也有這樣的問題。
(關於@Async的用法,請參考:http://blog.csdn.net/clementad/article/details/47403185)測試
緣由:
spring 在掃描bean的時候會掃描方法上是否包含@Transactional註解,若是包含,spring會爲這個bean動態地生成一個子類(即代理類,proxy),代理類是繼承原來那個bean的。此時,當這個有註解的方法被調用的時候,其實是由代理類來調用的,代理類在調用以前就會啓動transaction。然而,若是這個有註解的方法是被同一個類中的其餘方法調用的,那麼該方法的調用並無經過代理類,而是直接經過原來的那個bean,因此就不會啓動transaction,咱們看到的現象就是@Transactional註解無效。.net
爲何一個方法a()調用同一個類中另一個方法b()的時候,b()不是經過代理類來調用的呢?能夠看下面的例子(爲了簡化,用僞代碼表示):debug
@Service class A{ @Transactinal method b(){...} method a(){ //標記1 b(); } } //Spring掃描註解後,建立了另一個代理類,併爲有註解的方法插入一個startTransaction()方法: class proxy$A{ A objectA = new A(); method b(){ //標記2 startTransaction(); objectA.b(); } method a(){ //標記3 objectA.a(); //因爲a()沒有註解,因此不會啓動transaction,而是直接調用A的實例的a()方法 } }
當咱們調用A的bean的a()方法的時候,也是被proxy$A攔截,執行proxy$A.a()(標記3),然而,由以上代碼可知,這時候它調用的是objectA.a(),也就是由原來的bean來調用a()方法了,因此代碼跑到了「標記1」。因而可知,「標記2」並無被執行到,因此startTransaction()方法也沒有運行。代理
瞭解了失效的緣由,解決的方法就簡單了(兩種):
把這兩個方法分開到不一樣的類中;
把註解加到類名上面;code
參考:
http://stackoverflow.com/questions/18590170/transactional-does-not-work-on-method-levelblog
---------------------
做者:Clement-Xu
來源:CSDN
原文:https://blog.csdn.net/clementad/article/details/47339519
繼承