概览
一个事务(Transaction)包含一系列数据库操作,这些操作要么全部成功,要么全部失败,被视为一个整体,保证ACID(原子性、持久性、一致性和隔离性)特性。
事务对于需要确保数据完整性的操作至关重要,例如金融转账操作:需要从一个账户扣除转账金额,同时将相同金额增加到另一个账户。
目前,一个会话仅支持一个正在运行的事务。
事务的生命周期与控制
事务的生命周期遵循一个清晰的三步流程:
- 启动:明确启动一个事务。
- 执行:执行数据库操作。
- 结束:提交或回滚事务。
- COMMIT(提交):将事务中的所有操作永久应用到数据库中。
- ROLLBACK(回滚):放弃事务中的所有操作,将数据库恢复到事务开始之前的状态。
事务中的写操作在执行COMMIT之前都是暂存的,尚未生效。任何未提交的更改都可以通过ROLLBACK撤销。
锁机制
当一个事务发生时,嬴图利用锁来防止后续事务对数据进行更新或删除,从而维护隔离性和一致性。
因此,及时结束每个事务(通过COMMIT或ROLLBACK)至关重要。事务长时间保持开启状态可能导致阻塞,影响其他进程。
事务超时
如果事务在一定时间内处于空闲状态(即没有执行新的操作),嬴图会自动通过ROLLBACK终止该事务。
显示事务
显示数据库中所有正在运行的事务:
SHOW TRANSACTION
每个事务有如下信息:
字段 |
描述 |
---|---|
graph_name |
事务正在执行的图的名称 |
session_id |
会话ID |
transaction_id |
事务ID |
current_query |
事务中最后执行的操作 |
start_time |
事务启动的时间 |
elapsed_time |
事务启动以来经过的时间 |
extra_info |
关于事务的其他信息 |
启动事务
为当前图启动一个新事务:
START TRANSACTION
一旦事务启动,你就可以在该事务中对当前图执行读写操作。
回滚事务
放弃事务中的所有操作并结束该事务:
ROLLBACK
提交事务
将事务中的所有操作应用到数据库并结束该事务:
COMMIT
示例
以下示例演示如何启动一个事务并执行三项操作:
- 在账户
a78
与a9002
之间插入一条Transfer
边 - 更新账户
a78
的余额 - 更新账户
a9002
的余额
最后,将事务提交到数据库。
START TRANSACTION;
MATCH (a1:Account {_id: "a78"}), (a2:Account {_id: "a9002"})
INSERT (a1)-[:Transfer {amount: 1000, time: local_datetime("2025-11-09 03:02:11")}]->(a2);
MATCH (n:Account {_id: "a78"}) SET n.balance = n.balance - 1000;
MATCH (n:Account {_id: "a9002"}) SET n.balance = n.balance + 1000;
COMMIT;
或者,你可以回滚事务以放弃所有更改:
START TRANSACTION;
MATCH (a1:Account {_id: "a78"}), (a2:Account {_id: "a9002"})
INSERT (a1)-[:Transfer {amount: 1000, time: local_datetime("2025-11-09 03:02:11")}]->(a2);
MATCH (n:Account {_id: "a78"}) SET n.balance = n.balance - 1000;
MATCH (n:Account {_id: "a9002"}) SET n.balance = n.balance + 1000;
ROLLBACK;