@Enrico The problem is that an operation should be rejected not only if the version mismatched, but also if the mark node did not exist even if the version matched.
@Andor Thanks for your clarification. Let's then refer it as multi op. Actually I want something like LeaderLatch of Curator but the implementation in Curator has some wart[1] so that I need to reimplement it by myself. The semantic "bulk operations" can also fit my case if ZooKeeper ensures the check is immediately followed by setData. Since check doesn't commit a modification the problem that it wouldn't roll back doesn't matter. @Michael Thanks for your clarification, too. Now I know bulk operation won't take care of rolling back failed operations and thus it is different from traditional transactions. It is a misunderstanding from my side. Best, tison. [1] https://www.mail-archive.com/user@curator.apache.org/msg00912.html Michael Han <h...@apache.org> 于2019年8月15日周四 上午6:12写道: > >> Is there any way to do an "if-else" transaction? > > No for your use case. The only remotely related conditional operation you > can express with multi-op is by using check operator (Op.check), where you > can check a zNode's version and only execute subsequent operation in multi > op when version matches. Though, even this would only allow you to express > "if" rather than "if / else". > > >> ZooKeeper doesn’t support transactions to my best knowledge. It has a > `multi` operation feature, but that’s more like a bulk operation, not > transaction. > > Ted can correct me if I am wrong, since he added the multi op feature, but > my understanding is "multi op" is branded from day one as the transaction > support for zookeeper (we even provide an API with exact name: > Transaction). If we use the traditional semantic for transaction in > database context, the ACID properties multi-op satisfies at least atomicity > and durability. So saying zookeeper does not support transaction seems a > strong argument that against the properties of multi-op and existing > literatures related to zookeeper. On the other side, typically bulk > operations does not support atomicity, which will not take care of rolling > back failed operations. > > On Wed, Aug 14, 2019 at 9:33 AM Andor Molnar <an...@apache.org> wrote: > > > "it's said that ZooKeeper has a transaction mechanism” > > > > I’m still confused with this. ZooKeeper doesn’t support transactions to > my > > best knowledge. It has a `multi` operation feature, but that’s more like > a > > bulk operation, not transaction. > > > > "I want to tell ZooKeeper that the check and setData should be > successful” > > > > I don’t think you can do that. ZK has no check-and-set support either. > > > > Maybe we should step back first and see what’s your use case exactly that > > you’re trying to solve with ZooKeeper. I suspect that you’re trying to > > follow the wrong approach or misusing ZooKeeper. > > > > Have you checked our tutorial and recipes page? > > You can find some recommended usage patterns: > > https://zookeeper.apache.org/doc/r3.5.5/recipes.html > > https://zookeeper.apache.org/doc/r3.5.5/zookeeperTutorial.html > > > > If that’s not enough, you could also try Curator which has even more > > built-in high level functionalities on top of basic ZK commands. > > > > Andor > > > > > > > > > On 2019. Aug 14., at 17:52, Zili Chen <wander4...@gmail.com> wrote: > > > > > > Hi Andor, > > > > > > Thanks for your attention. > > > > > > The problem is that in concurrent scenario zk.setData() could still > > failed > > > if there is another thread delete the node. I know with proper lock > > strategy > > > and ownership separation this can be avoid but it's said that ZooKeeper > > has > > > a transaction mechanism so I'd like to see whether I can make use of > it. > > > > > > There is where I turn to > > > > > > zk.multi(Op.check(path1), Op.setData(path2, data)); // path1 == or != > > path2 > > > is irrelevant > > > > > > when the existence of a mark node(path1) guarded a condition and I want > > to > > > make > > > sure that setData successes only if the mark node exist. If I check the > > > existence > > > first and commit setData, a remove to the node could break the guard. > In > > > other > > > words, I want to tell ZooKeeper that the check and setData should be > > > successful > > > committed or fail to be committed atomically. > > > > > > Best, > > > tison. > > > > > > > > > Andor Molnar <an...@apache.org> 于2019年8月14日周三 下午11:12写道: > > > > > >> Hi Zili, > > >> > > >> There’s no such functionality in ZooKeeper as far as I’m concerned. I > > >> think your multi example (zk.multi(Op.check(path), Op.setData(path, > > data))) > > >> is already a usage pattern which multi is not designed to support. > > >> > > >> Why do you need to do this in “transactions” (there’s no transaction > in > > >> ZK)? > > >> > > >> In Java you can do: > > >> > > >> try { > > >> zk.create(); > > >> } catch (NodeExistsException e) { > > >> // swallow exception > > >> } > > >> zk.setData(); > > >> … > > >> > > >> Regards, > > >> Andor > > >> > > >> > > >> > > >> > > >>> On 2019. Aug 6., at 14:44, Zili Chen <wander4...@gmail.com> wrote: > > >>> > > >>> Hi Enrico, > > >>> > > >>> Thanks for your reply. > > >>> > > >>>> In this case usually you use conditional setData, using the > 'version' > > of > > >>>> thr znode > > >>> > > >>> > > >>> what if the caller has no idea on whether the node exist?(see also > > >>> my if-else pseudo-code above.) > > >>> > > >>> IIRC if we call `setData` on a non-exist path a NoNodeException > > >>> will be thrown. > > >>> Best, > > >>> tison. > > >>> > > >>> > > >>> Enrico Olivelli <eolive...@gmail.com> 于2019年8月6日周二 下午8:27写道: > > >>> > > >>>> Il mar 6 ago 2019, 13:47 Zili Chen <wander4...@gmail.com> ha > scritto: > > >>>> > > >>>>> Any ideas? > > >>>>> > > >>>>> > > >>>>> Zili Chen <wander4...@gmail.com> 于2019年7月29日周一 上午11:12写道: > > >>>>> > > >>>>>> Hi ZooKeepers, > > >>>>>> > > >>>>>> Currently our transaction mechanism supports doing > > >>>>>> create/setData/checkExist/delete in transaction. However, taking > > this > > >>>>>> scenario into consideration, we want to put data in path "/path" > but > > >>>>>> don't know whether the znode exists or not. Let's say we program > as > > >>>>>> below > > >>>>>> > > >>>>>> if (zk.exist(path)) { > > >>>>>> zk.setData(path, data); > > >>>>>> } else { > > >>>>>> zk.create(path, data); > > >>>>>> } > > >>>>> > > >>>> > > >>>> Do you need to perform other ops in the same transaction? > > >>>> In this case usually you use conditional setData, using the > 'version' > > of > > >>>> thr znode > > >>>> > > >>>> > > >>>> Enrico > > >>>> > > >>>>> > > >>>>>> if we want to do the check and "put" in transaction, it would be > > like > > >>>>>> > > >>>>>> zk.multi(Op.check(path), Op.setData(path, data)); > > >>>>>> > > >>>>>> but we cannot add a "else" branch. ZooKeeper's transaction would > all > > >>>>>> success or fail. > > >>>>>> > > >>>>>> Is there any way to do an "if-else" transaction? > > >>>>>> > > >>>>>> Best, > > >>>>>> tison. > > >>>>>> > > >>>>> > > >>>> > > >> > > >> > > > > >