spring data mongodb 如何以事物的方式進行增刪改查

gongchengship發表於2024-07-17

在Spring Data MongoDB中使用事務(transactions)來進行增刪改查操作可以確保這些操作要麼全部成功,要麼全部失敗,從而保證資料的一致性。以下是使用Spring Data MongoDB事務的一些關鍵步驟和示例:

前提條件

  1. MongoDB版本:確保你使用的MongoDB版本為4.0或更高,因為事務支援是從4.0版本開始引入的。
  2. 副本集:事務只能在副本集(Replica Set)或分片叢集(Sharded Cluster)上使用,不能在單節點MongoDB例項上使用。

配置Spring Boot專案

確保在你的Spring Boot專案中引入了spring-boot-starter-data-mongodb依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置MongoDB事務管理器

在Spring Boot專案中,配置MongoDB事務管理器通常在配置類中完成:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;

@Configuration
public class MongoConfig {

    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }
}

使用事務進行增刪改查

使用Spring的@Transactional註解來管理事務。在你的服務類中,注入你需要的Repository,然後在帶有@Transactional註解的方法中進行增刪改查操作。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Autowired
    private MyRepository myRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Transactional
    public void performTransaction() {
        // 插入操作
        MyDocument doc1 = new MyDocument("doc1");
        myRepository.save(doc1);

        // 更新操作
        MyDocument doc2 = myRepository.findById("doc2Id").orElseThrow(() -> new RuntimeException("Document not found"));
        doc2.setName("updatedName");
        myRepository.save(doc2);

        // 刪除操作
        myRepository.deleteById("doc3Id");

        // 查詢操作
        MyDocument doc4 = myRepository.findById("doc4Id").orElseThrow(() -> new RuntimeException("Document not found"));
        System.out.println("Retrieved Document: " + doc4);
    }
}

Repository介面

定義你的Repository介面:

import org.springframework.data.mongodb.repository.MongoRepository;

public interface MyRepository extends MongoRepository<MyDocument, String> {
}

文件類

定義你的文件類:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "my_collection")
public class MyDocument {

    @Id
    private String id;
    private String name;

    // 建構函式、getter和setter
    public MyDocument(String name) {
        this.name = name;
    }

    // getter和setter
}

事務回滾

當事務中的任何操作丟擲異常時,事務將回滾。你可以透過自定義異常來觸發回滾:

import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Autowired
    private MyRepository myRepository;

    @Transactional(rollbackFor = CustomException.class)
    public void performTransaction() throws CustomException {
        // 事務操作
        try {
            // 插入操作
            MyDocument doc1 = new MyDocument("doc1");
            myRepository.save(doc1);

            // 更新操作
            MyDocument doc2 = myRepository.findById("doc2Id").orElseThrow(() -> new RuntimeException("Document not found"));
            doc2.setName("updatedName");
            myRepository.save(doc2);

            // 刪除操作
            myRepository.deleteById("doc3Id");

            // 模擬異常
            if (true) {
                throw new CustomException("Custom Exception Occurred");
            }

        } catch (Exception e) {
            throw new CustomException("Exception during transaction", e);
        }
    }
}
public class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }

    public CustomException(String message, Throwable cause) {
        super(message, cause);
    }
}

完。

相關文章