spring 事務失效的幾種場景
阿新 • • 發佈:2021-08-30
以下場景是基於mysql資料庫,InnoDB的儲存引擎。
一.沒有新增@Transactional註解
二.方法宣告是private或者static
三.沒有丟擲異常而是try catch了異常
下面這種情況,事務不會回滾
@Transactional public void insertUser(String name){ try { User user = new User(); user.setName(name); userDao.insertUser(user); //模擬拋異常 throw new RuntimeException(); } catch (RuntimeException e) { e.printStackTrace(); } }
四.異常型別不對
預設只對runtimeException的型別進行回滾,如果丟擲Exception異常是不進行回滾的,如果想回滾要配置@Transactional(rollbackFor = Exception.class)
@Transactional public void insertUser(String name) throws Exception { User user = new User(); user.setName(name); userDao.insertUser(user); //模擬拋異常 throw new Exception(); }
五.自己調自己
下面這種情況,事務是不生效的,如果要生效,可以把this呼叫放到另外一個類,insertStu這個放另外一個類,這樣可以這個方法有事務
public void insertUser(String name) { User user = new User(); user.setName(name); //沒有事務,不會回滾,儲存成功 userDao.insertUser(user); insertStu(name); } @Transactional public void insertStu(String name){ Stu stu = new Stu(); stu.setName(name); //沒有事務,儲存會成功 stuDao.insertUser(stu); throw new RuntimeException(); }
下面這種情況,事務是生效的,注意
@Transactional
public void insertUser(String name) {
User user = new User();
user.setName(name);
//有事務,會回滾,儲存不成功
userDao.insertUser(user);
insertStu(name);
}
public void insertStu(String name){
Stu stu = new Stu();
stu.setName(name);
//有事務,會回滾,儲存不成功
stuDao.insertUser(stu);
throw new RuntimeException();
}
六.沒有配置正確的事務管理器
如果專案中是多資料來源情況,要單獨配置事務管理器。當引入jdbc依賴之後,Spring Boot會自動預設分別注入DataSourceTransactionManager或JpaTransactionManager,
所以我們不需要任何額外配置就可以用@Transactional註解進行事務的使用。