1. 程式人生 > >iBATIS事務處理淺析

iBATIS事務處理淺析

iBATIS事務處理這部分是和Dao緊密相聯的。

我們在使用Dao時,如以下程式碼,先插入新記錄,再進行更新:

  1. personDao.insertPerson (person); // Starts transaction
  2. person.setLastName("Begin");  
  3. personDao.updatePerson (person); // Starts a new transaction

因為沒有顯式地啟動事務,iBatis會認為這是兩次事務,分別從連線池中取兩次Connectio。

我們所寫的Dao子類(繼承自com.ibatis.dao.client.template.SqlMapDaoTemplate)的每一個Dao方法已經預設為一個事務(通過動態代理)。

而在業務層,應該有一個類來統管Dao子類的事務,iBatis是通過DaoManager類來作這件事的,如下:

DaoManager provides access to all DAOs it manages and also allows transactions to be committed and ended (possibly rolled back)

眾Dao子類由DaoManager產生,如:

  1. DaoManager daoManager = DaoManagerBuilder.buildDaoManager(reader);  
  2. UserDao userDao = (UserDao) daoManager.getDao(UserDao.class); 

UserDao是使用者自己定義的介面,獲得的其實是在dao.xml中指定的相對應的 SqlMapDao實現類,從而實現了鬆藕合。在良好的分層設計中,

iBATIS事務處理之業務層(service包)只需要知道Dao介面,而不去關心其具體怎麼實現。

如果顯式地宣告事務處理語句,如下:

  1. try {  
  2. daoManager.startTransaction();  
  3. personDao.insertPerson (person);   
  4. person.setLastName("Begin");  
  5. personDao.updatePerson(person);   
  6. otherDao.doSomething(other);  
  7. ...  
  8. daoManager.commitTransaction();  
  9. finally {  
  10. daoManager.endTransaction();  

這樣就保持了原子性,整體為一個事務,要麼全部執行成功,否則回滾。

現在唯一的問題就是,dao層的事務是否已經放棄,否則產生事務巢狀問題對效能會有影響

當然,iBatis 完全可以這麼做:建一個宣告式介面:IService,再使用動態代理,將使用者自己的Serivce子類通過動態代理自動包上事務處理的程式碼,默 認每一個業務方法為一個事務。

大師的心如果能輕易揣測,就是不大師了:),估計大師認為這樣屬於過度設計,他認為把這種靈活性交給使用者是合適的,相當多的service 方法只調用一個Dao方法,例如CRUD操作。

再補充一下,iBatis中對事務的處理是可配置的,最常用的Type是"JDBC",也可以宣告為"JTA"或"EXTERNAL".