From 1432bdc9ab245806454ffc0760fa5cde7393d04c Mon Sep 17 00:00:00 2001 From: Balachandar Namasivayam Date: Fri, 1 Mar 2019 18:25:35 -0800 Subject: [PATCH 1/3] Document behavior on the ordering of writes and read conflict ranges --- documentation/sphinx/source/developer-guide.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/sphinx/source/developer-guide.rst b/documentation/sphinx/source/developer-guide.rst index 55c8303b8d..c786cd2e7e 100644 --- a/documentation/sphinx/source/developer-guide.rst +++ b/documentation/sphinx/source/developer-guide.rst @@ -586,6 +586,8 @@ Conflicts can be *avoided*, reducing isolation, in two ways: Conflicts can be *created*, increasing isolation, by :ref:`explicitly adding ` read or write conflict ranges. +.. warning:: Ordering of writes and read conflict ranges should be considered carefully as it could result in unexpected behavior. Adding read conflict ranges will skip adding conflicts for the range of keys that have been written previously in the transaction. Adding them before the respective writes will add to the conflict ranges. + For example, suppose you have a transactional function that increments a set of counters using atomic addition. :ref:`developer-guide-atomic-operations` do not add read conflict ranges and so cannot cause the transaction in which they occur to fail. Most of the time, this is exactly what we want. However, suppose there is another transaction that (infrequently) resets one or more counters, and our contract requires that we must advance all specified counters in unison. We want to guarantee that if a counter is reset during an incrementing transaction, then the incrementing transaction will conflict. We can selectively add read conflicts ranges for this purpose:: @fdb.transactional From b0c910fba536da49acef1b239f0d5e1b87d90297 Mon Sep 17 00:00:00 2001 From: Balachandar Namasivayam Date: Mon, 4 Mar 2019 12:31:47 -0800 Subject: [PATCH 2/3] Update documentation. --- documentation/sphinx/source/developer-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/sphinx/source/developer-guide.rst b/documentation/sphinx/source/developer-guide.rst index c786cd2e7e..b6f73e8b3c 100644 --- a/documentation/sphinx/source/developer-guide.rst +++ b/documentation/sphinx/source/developer-guide.rst @@ -586,7 +586,7 @@ Conflicts can be *avoided*, reducing isolation, in two ways: Conflicts can be *created*, increasing isolation, by :ref:`explicitly adding ` read or write conflict ranges. -.. warning:: Ordering of writes and read conflict ranges should be considered carefully as it could result in unexpected behavior. Adding read conflict ranges will skip adding conflicts for the range of keys that have been written previously in the transaction. Adding them before the respective writes will add to the conflict ranges. +.. warning:: Ordering of *write* operations and *add read conflict range* operations should be considered carefully as it could result in unexpected behavior. Adding read conflict ranges will skip adding conflicts for the range of keys that have been written previously in the transaction. Adding them before the respective writes will add to the conflict ranges. For example, suppose you have a transactional function that increments a set of counters using atomic addition. :ref:`developer-guide-atomic-operations` do not add read conflict ranges and so cannot cause the transaction in which they occur to fail. Most of the time, this is exactly what we want. However, suppose there is another transaction that (infrequently) resets one or more counters, and our contract requires that we must advance all specified counters in unison. We want to guarantee that if a counter is reset during an incrementing transaction, then the incrementing transaction will conflict. We can selectively add read conflicts ranges for this purpose:: From ee7ee3e78376c7d08037cee3867cf2b63ab6c76b Mon Sep 17 00:00:00 2001 From: Balachandar Namasivayam <36455962+bnamasivayam@users.noreply.github.com> Date: Mon, 4 Mar 2019 15:17:25 -0800 Subject: [PATCH 3/3] Update documentation/sphinx/source/developer-guide.rst --- documentation/sphinx/source/developer-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/sphinx/source/developer-guide.rst b/documentation/sphinx/source/developer-guide.rst index b6f73e8b3c..efaf4e7112 100644 --- a/documentation/sphinx/source/developer-guide.rst +++ b/documentation/sphinx/source/developer-guide.rst @@ -586,7 +586,7 @@ Conflicts can be *avoided*, reducing isolation, in two ways: Conflicts can be *created*, increasing isolation, by :ref:`explicitly adding ` read or write conflict ranges. -.. warning:: Ordering of *write* operations and *add read conflict range* operations should be considered carefully as it could result in unexpected behavior. Adding read conflict ranges will skip adding conflicts for the range of keys that have been written previously in the transaction. Adding them before the respective writes will add to the conflict ranges. +.. note:: *add read conflict range* behaves as if the client is reading the range. This means *add read conflict range* will not add conflict ranges for keys that have been written earlier in the same transaction. This is the intended behavior, as it allows users to compose transactions together without introducing unnecessary conflicts. For example, suppose you have a transactional function that increments a set of counters using atomic addition. :ref:`developer-guide-atomic-operations` do not add read conflict ranges and so cannot cause the transaction in which they occur to fail. Most of the time, this is exactly what we want. However, suppose there is another transaction that (infrequently) resets one or more counters, and our contract requires that we must advance all specified counters in unison. We want to guarantee that if a counter is reset during an incrementing transaction, then the incrementing transaction will conflict. We can selectively add read conflicts ranges for this purpose::