以下是使用 sqlite_orm 库进行事务操作的完整示例,包含事务的提交(commit)和回滚(rollback)场景:
1. 准备工作
首先确保已安装 sqlite_orm
。可以通过以下方式安装:
git clone https://github.com/fnc12/sqlite_orm.git
2. 示例代码
#include <sqlite_orm/sqlite_orm.h>
#include <iostream>
#include <stdexcept>
using namespace sqlite_orm;
// 定义数据结构
struct User {
int id;
std::string name;
double balance; // 用户余额
};
int main() {
// 创建数据库和表
auto storage = make_storage("transaction_example.db",
make_table("users",
make_column("id", &User::id, primary_key()),
make_column("name", &User::name),
make_column("balance", &User::balance)
)
);
// 同步表结构(如果不存在则创建)
storage.sync_schema();
// 插入初始数据
storage.replace(User{1, "Alice", 1000.0});
storage.replace(User{2, "Bob", 500.0});
try {
// ==== 开始事务 ====
auto guard = storage.transaction_guard();
// 模拟转账操作:Alice向Bob转账200元
auto alice = storage.get<User>(1);
auto bob = storage.get<User>(2);
if (alice.balance >= 200) {
alice.balance -= 200;
bob.balance += 200;
storage.update(alice);
storage.update(bob);
std::cout << "转账成功: Alice -> Bob $200" << std::endl;
// ==== 显式提交事务 ====
guard.commit();
} else {
std::cerr << "转账失败: Alice余额不足" << std::endl;
// guard析构时会自动回滚(无需显式调用)
}
} catch (const std::exception& e) {
std::cerr << "事务异常: " << e.what() << std::endl;
// guard析构时会自动回滚
}
// 验证结果
auto users = storage.get_all<User>();
for (const auto& user : users) {
std::cout << "用户: " << user.name
<< ", 余额: $" << user.balance << std::endl;
}
return 0;
}
关键点解析
事务保护对象
transaction_guard()
:创建一个RAII风格的事务保护对象,析构时自动决定回滚(除非已调用commit()
)。显式提交
guard.commit()
:只有调用此方法后,事务中的操作才会生效。自动回滚
- 如果未调用
commit()
,guard
析构时会自动回滚。 - 发生异常时也会触发自动回滚。
- 如果未调用
错误处理
- SQL操作可能抛出异常(如主键冲突、约束错误等)。
try-catch
块确保程序健壮性。
运行结果
- 成功场景:输出转账后的余额。
- 失败场景(如余额不足或异常):所有修改会被回滚,数据保持原状。
如果需要更复杂的事务嵌套或手动控制事务生命周期,可以改用 begin_transaction()
+ rollback()
/commit()
API。
内容由零声教学AI助手提供,问题来源于学员提问