MST
星途 面试题库

面试题:Swift的Vapor框架中如何实现数据库的连接与事务处理

在使用Vapor框架开发服务器端应用时,要求连接MySQL数据库,并实现一个转账功能。在转账过程中涉及到从一个账户扣除金额,向另一个账户增加金额,这两个操作需要在一个事务中完成,以确保数据的一致性。请用Swift代码展示如何在Vapor框架中配置MySQL数据库连接,以及如何实现上述事务处理逻辑。
17.4万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试
  1. 配置MySQL数据库连接: 首先在Package.swift文件中添加MySQL依赖:

.package(url: "https://github.com/vapor/mysql.git", from: "4.0.0")

然后在`targets`部分添加:
```swift
.target(
    name: "App",
    dependencies: [
       .product(name: "MySQL", package: "mysql")
    ]
)

configure.swift文件中配置数据库连接:

import MySQL

try app.databases.use(.mysql(
    hostname: "localhost",
    username: "your_username",
    password: "your_password",
    database: "your_database"
), as:.mysql)
  1. 实现事务处理逻辑: 假设我们有两个账户表accounts,表结构包含id(唯一标识),balance(账户余额)。 定义账户模型:
    final class Account: Model, Content {
        static let schema = "accounts"
    
        @ID(key:.id)
        var id: UUID?
    
        @Field(key: "balance")
        var balance: Double
    
        init() {}
    
        init(id: UUID? = nil, balance: Double) {
            self.id = id
            self.balance = balance
        }
    }
    
    实现转账功能:
    func transfer(from fromAccountID: UUID, to toAccountID: UUID, amount: Double, on req: Request) async throws {
        try await req.transaction { conn in
            let fromAccount = try await Account.find(fromAccountID, on: conn)
            guard let from = fromAccount else {
                throw Abort(.notFound, reason: "From account not found")
            }
            let toAccount = try await Account.find(toAccountID, on: conn)
            guard let to = toAccount else {
                throw Abort(.notFound, reason: "To account not found")
            }
            if from.balance < amount {
                throw Abort(.badRequest, reason: "Insufficient funds")
            }
            from.balance -= amount
            to.balance += amount
            try await from.save(on: conn)
            try await to.save(on: conn)
        }
    }
    
    这里transfer函数接收转账的源账户ID、目标账户ID和转账金额,在事务中确保两个账户的余额更新操作要么都成功,要么都失败,从而保证数据一致性。