在计算机科学和数据库领域,事务是指作为一个不可分割的操作序列,要么全部执行,要么全部不执行的一组数据库操作。事务通常具有以下四个特性,即ACID:
Atomicity(原子性):事务中的所有操作要么全部执行成功,要么全部不执行,不会出现部分执行的情况。
Consistency(一致性):事务执行前后,数据库的状态必须保持一致,即事务执行后数据库从一个一致的状态转换到另一个一致的状态。
Isolation(隔离性):事务的执行不会受到其他事务的影响,即一个事务的执行过程中对其他事务是隔离的。
Durability(持久性):一旦事务提交,其结果应该是永久性的,即对数据库的影响是持久的。
在 ZooKeeper 中,没有直接提供 transaction() 方法来执行多个操作的原子性。但是,ZooKeeper 提供了 multi() 方法来实现原子性的多个操作。multi() 方法允许客户端将多个操作放在一个事务中,然后一次性提交给 ZooKeeper 服务器,这样可以确保这些操作要么全部成功,要么全部失败。
org.apache.zookeeper.Transaction transaction()
事务是 multi(java.lang.Iterable) 方法的精简封装,它提供了一个构建器对象,可用于构建和提交一组原子操作。
下面示例演示使用事务一次性常见多个节点和删除一个节点,代码如下:
package com.hxstrive.zookeeper; import com.alibaba.fastjson.JSONObject; import org.apache.zookeeper.*; import org.junit.Before; import org.junit.Test; import java.util.List; /** * zookeeper 事务操作 * @author hxstrive.com */ public class TransactionNode { private static ZooKeeper zooKeeper; @Before public void init() throws Exception { zooKeeper = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() { public void process(WatchedEvent watchedEvent) { System.out.println("触发了 " + watchedEvent.getType() + " 事件"); } }); } @Test public void syncDemo() throws Exception { // 开启事务 Transaction transaction = zooKeeper.transaction(); // 创建多个节点 zooKeeper.create("/trans_node", "new value".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zooKeeper.create("/trans_node/node1", "data1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zooKeeper.create("/trans_node/node2", "data2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zooKeeper.create("/trans_node/node3", "data3".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); // 删除一个节点 zooKeeper.delete("/trans_node/node3", -1); // 提交事务 List<OpResult> resultList = transaction.commit(); for(OpResult opResult : resultList) { System.out.println("结果:" + JSONObject.toJSONString(opResult)); } } }
当然,我们也可以直接使用带有参数的 List<org.apache.zookeeper.OpResult> multi(Iterable<org.apache.zookeeper.Op> ops) 方法替代。