1. 程式人生 > 其它 >spring 事務失效的幾種場景

spring 事務失效的幾種場景

以下場景是基於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註解進行事務的使用。