Если транзакции по REST недостижимы, как REST может когда-либо быть действительно полезным?

При изучении REST одна из первых вещей, вероятно, кто-нибудь заметит, что определенная семантика транзакций не определена, некоторые говорят, что это неявно против того, что REST, в то время как другие говорят, что любая попытка сделать это приведет к "заражению", системы REST.

Но мы можем сказать, что REST действительно стал популярным выбором "api", и каждый сайт в юниверсе начал показывать спокойные точки входа.

Как именно они могут использоваться без транзакционного поведения (и я говорю, что они не компенсируют)? потому что мне кажется, что одним из преимуществ REST является то, что он разбивает компоненты данных, это, по вашему мнению, открывает их для того, чтобы интеллектуальные клиенты составляли данные (и добавляли и настраивали такие скомпонованные данные) из нескольких сервисов. Но если я не могу выполнить свои изменения в этом составе данных атомарно и изолированно, то использование REST становится бесполезным.

По прошествии времени и необходимость получения серьезной информации, мы хотим получить то, что есть: просто (REST выигрывает там) и поддерживает транзакционное поведение, поэтому мы можем надежно управлять этими данными.

Теперь, я несколько раз читал конкретный аргумент в своих исследованиях, и это связано с тем, как мы должны думать о транзакциях в REST, а приведенный пример - это корзина для покупок, где вы неявно имеете изоляцию потому что тележка ВАША.

Однако я не согласен с этим аргументом: во-первых, изоляция корзины покупок просто удобна, это не изолированность транзакций. Что произойдет, если я одновременно выполняю операцию против своей тележки, пока какая-то часть моего приложения читает данные от него? Я бы не ожидал, что часть чтения моего приложения увидит данные, которые все еще находятся в транзакции.

Не говоря уже о том, что не все изменения данных имеют неявную модель транзакции, транзакции по нескольким сервисам определенно не соответствуют.

Мне кажется, что транзакции должны произойти и должны произойти таким образом, чтобы фактические вызовы REST не знали об этом (добавив, что остальная полезная нагрузка является большой, нет, но добавление заголовков в порядке).

Я прочитал несколько предложений о том, как модель транзакций может быть создана над REST, а некоторые из написанных спецификаций выглядят очень недавно.

Есть ли какие-то реальные мысли об этом? не должно быть что-то "больше", чем REST, чтобы упрощенную природу REST можно было использовать против сплошного манипулирования данными ( "кислотные" транзакции).

Если мы не ожидаем, что мы будем продвигать анте и расскажем разработчикам услуг, что если они хотят взаимодействовать в чистом мире данных, им нужно поддерживать что-то, возможно, монолитное, как мыло? или еще хуже попытаться построить свою собственную поддержку транзакций в нечто вроде REST, что делает каждую службу нестандартной и нарушает всю мощность REST?

Заранее благодарим за любые мысли.


Изменить, добавлен короткий сценарий:

Представьте клиентскую форму, которая обрабатывает создание альбома, для удобства в этом альбоме, вместо того, чтобы просить пользователя дать uri для ресурса исполнителя, они могут выбрать из списка художников (скорее всего, GET'd из каталог художников).

Для удобства использования клиент может написать имя исполнителя вручную, чтобы создать художник "inline".. в сценарии проводки код клиента понимает это, и перед отправкой запроса на создание альбома он, во-первых, пытается определить, существует ли художник, если это так, получает ури для этого художника, в противном случае создает художника и получает художников uri.

Затем клиентский код продолжает создавать альбом, это умнее обычного клиента, он не сидит прямо над REST и "тупо", но вместо этого имеет некоторое взаимодействие, которое обрабатывает более чистую логику REST.

Однако в этом случае было бы неплохо гарантировать, что художник не создан, если альбом не создан, поскольку сначала создается художник.

Это не так важно, как предполагала транзакция, но определяет набор действий, которые клиентский код предпочел бы выполнять как одну операцию (в конце концов, это делает это похожим на одну операцию на пользователь).

Единственное руководство, которое я видел для этого сценария, - это заставить клиента компенсировать действие в случае сбоя в создании альбома и специально вызвать удаление исполнителя. Но это кажется проблематичным, потому что клиент предполагает, что художник был изолирован, что маловероятно, как может быть, что произойдет, если другой клиент уже "увидел" этого исполнителя и назначил ему?

Это мои проблемы в отношении внесения изменений в данные, и в то время как есть, конечно, другие пробелы (кто говорит, что художник не может быть просто удален позже), эти действия НЕ прозрачны (т.е. действия не являются что-то автоматизированное клиентом, но что-то специально запросило у пользователя).

Я надеюсь, что это поможет осветить тему.

Ответ 1

Я собираюсь предположить, что когда вы говорите о транзакциях, вы говорите о распределенном протоколе Two Phase Commit.

Если я правильно понимаю, вы пытаетесь понять, как мы могли бы использовать REST для выполнения операций, охватывающих несколько систем, если REST не может поддерживать транзакции через различные запросы REST. Проблема в том, что вы делаете потенциально ошибочное предположение, что мы должны использовать транзакции для достижения согласованности. Какую цену мы платим за их использование, и какие существуют альтернативы?

Пэт Хелланд, который работал в Amazon и сейчас находится в Microsoft, написал статью "Жизнь за пределами распределенных транзакций" . В статье автор делает следующее утверждение:

К сожалению, программисты, стремящиеся решать бизнес-цели, такие как электронная коммерция, управление цепочками поставок, финансовые, и медико-санитарные услуги все больше нужно думать о масштабирование без распространения сделки. Они делают это, потому что попытки использовать распределенные транзакции слишком хрупкие и плохо работают.

В его статье рассматриваются альтернативные решения для распределенных транзакций, которые масштабируются и хорошо работают.

Возможно, REST будет успешным, поскольку он не поддерживает транзакции. Вот цитата из Роя Филдинга, парня, который придумал термин REST

Если вы нуждаетесь в распределенный протокол транзакции, то как вы можете сказать, что ваш архитектура основана на REST? я просто не вижу, как вы можете одна ситуация (использование RESTful состояние приложения на клиенте и гипермедиа для определения всего состояния переходы) к следующей ситуации нуждаются в распределенном соглашении семантика транзакции, в которой клиент должен сообщить серверу, как управлять своими собственными ресурсами.

... на данный момент я считаю "отдых" транзакция "должна быть оксюмороном.

Это сообщение из списка REST-discuss от 9 июня 2009 года. Я не могу предоставить ссылку, потому что группы Yahoo бесполезны.

Ответ 2

Если вам нужны транзакции в приложении ReST, в функции ReST API, это обычно происходит потому, что у вас по-прежнему есть ваш компьютерный веб-сервисный веб-сайт.

Посмотрите на это по-другому.

Мыло googles: Откройте транзакцию, создайте запись клиента, создайте запись заказа, совершите транзакцию.

ReST googles: Спросите у сервера, что делать. Сервер говорит "создать клиентский ресурс", поэтому POST/клиенты. Сервер говорит: "Теперь создайте заказ, если хотите", клиент создает заказ, следуя форме.

В ReST протокол приложения выражается в терминах создаваемых и управляемых ресурсов, а не в терминах данных, имеющих границы транзакций.

Если вы хотите иметь длительную транзакцию, которая охватывает все эти операции, это сервер, который решает запустить его, а не клиент.

Вы по-прежнему можете выполнять долгосрочные транзакции на стороне сервера. Если вы пытаетесь получить транзакции со стороны клиента, то вы предполагаете, что клиент уже знает все операции, которые он выполняет, и границы транзакций, существующие между этими операциями. Если вы считаете, что ваши ожидания от клиента, вы уже отказались от поздней привязки, связанной с гипермедией архитектуры отдыха.

Итак, если вы не делаете ReST и пытаетесь поместиться в RPC через http, у вас возникнет проблема с отсутствием транзакций.

Ответ 3

Я думаю, что большинство действий, которые обычно требуют транзакций, могут быть переработаны без них.

Например, классический банковский перевод. Предположим, что я хочу переместить $100 со счета A в B:

Begin Transaction
  /Debit  A, $100  
  /Credit B, $100
Commit Transaction

Это может быть переработано как:

 /Transfer  A, B, $100  

Таким образом, сервер может сделать это в два этапа, но действие с клиентом представляет собой единую, атомную операцию, которая имеет логический смысл.

Я уверен, что есть много примеров, когда удобнее всего делать все или ничего с набором операций (и мне любопытно, что люди могут придумать для их решения), но я обычно переделываю вещи в этом путь.

Ответ 4

Операция REST может запускать транзакцию, выполнять несколько операций с базой данных или другими транзакционными операциями, а затем совершать или откатывать - все в рамках транзакции.

То, что REST не может сделать, должно быть иначе, чем корень транзакции. Вы не можете начать транзакцию, затем выполнить две операции REST и операцию с базой данных, а затем передать их вместе. Это так же, как ситуация с веб-службами ASMX в .NET. Они могут быть корнем транзакции, но все. Они были успешными в течение многих лет, пока WCF не был представлен, поддерживая WS-транзакции. Даже сегодня и используя WCF, большинство операций веб-сервиса не обязательно должны быть транзакционными в том смысле, о котором вы просите.

Ответ 5

Я думаю, что транзакции с использованием REST действительно достижимы. Подумайте о транзакции как ресурсе, который вы можете создать (запустить), отредактировать (после изменения) и удалить (зафиксировать, отменить). Изменения, внесенные в транзакцию, не будут нуждаться в изменении глобального состояния до тех пор, пока транзакция не будет совершена, и во время фиксации вы можете применить любые глобальные правила согласованности состояния, которые вам нужны. Ресурс транзакций, конечно же, будет защищен с помощью правил авторизации.

Вы уже упоминали общую иллюстрацию для этой концепции:

Теперь, я несколько раз читал конкретный аргумент в своих исследованиях, и это связано с тем, как мы должны думать о транзакциях в REST, а приведенный пример - это корзина для покупок, где вы неявно имеете изоляцию потому что тележка ВАША.

Однако я не согласен с этим аргументом: во-первых, изоляция корзины покупок просто удобна, это не изолированность транзакций. Что произойдет, если я одновременно выполняю операцию против своей тележки, пока какая-то часть моего приложения читает данные от него? Я бы не ожидал, что часть чтения моего приложения увидит данные, которые все еще находятся в транзакции.

Почему бы вам не разрешить просмотр транзакции? Пока вы представляете его как то, что есть, список ожидающих изменений, это действительно полезно для обеспечения этой функции. Но если вы не хотите, чтобы он был доступен для просмотра, вы можете отключить GET на ресурсе.

Ответ 6

Взгляните на API OpenStreetMap. Я думаю, что это своего рода "REST", и он предоставляет вид "транзакций" - там называется "changeets". Это то, что вам нужно?

Ответ 7

Это интересная тема. Как вы уже упоминали, SOAP уже имеет такую ​​функциональность, но потребовалось много лет до того, как SOAP созрела до такой степени, что люди будут рассматривать реальную безопасность и транзакции с ней. До этого это была CORBA.

Различные полноценные расширения для SOAP, включая безопасность и транзакции, взяли много работы для многих людей, чтобы их правильно исправить. Это не произойдет с REST в одночасье, и это может никогда не произойти вообще.

Я чувствую, что большая часть популярности REST в настоящее время является чем-то вроде негативной реакции на плохо разработанные и чрезмерно сложные реализации SOAP, что является позором, потому что SOAP не обязательно должен быть таким. Как и в случае с чем-то еще, он нуждается в хорошем дизайне, чтобы он работал хорошо.

Ответ 8

Фактически, транзакции в REST работают так же, как транзакции должны работать в традиционных SOAP-сервисах.

Операции в стиле RPC, когда клиент выдает команду "начать транзакцию" (или какую-то операцию, которая неявно начинается, но не совершает транзакцию), а затем некоторые дополнительные операции, за которыми следует другая неявная/явная команда "конечная транзакция", устарели. Мир веб-служб давно отошел от модели RPC; RPC/закодированный в SOAP даже не совместим с WS-I!

Вместо процедур, службы SOAP сегодня построены вокруг концепции сообщений. Одно сообщение содержит всю информацию, необходимую для выполнения полной транзакции. Если вы отправляете заказ, сообщение OrderRequest будет содержать информацию о клиенте, информацию о заказе, детали заказа, детали оплаты... все, что серверу, возможно, потребуется знать об одном заказе.

У нас есть WS-Transactions, которые определяют семантику для распределенных транзакций, но они на самом деле не предназначены для поддержки семантики, подобной RPC, от клиента, они предназначены для оркестровки, когда вам нужно, чтобы несколько служб участвовали в одном и том же сделка. Например, вашему заказу необходимо заручиться услугой обработки платежей, чтобы подтвердить информацию о кредитной карте и отправить платеж, который необходимо отменить, если служба исполнения обнаруживает, что вы не в запасе, или что-то в этом роде... вы Получите эту идею. Все это происходит в среде сервера, поэтому на самом деле ничего не мешает вам делать то же самое в REST.

В REST у вас есть ресурсы вместо сообщений, но концепция действительно очень похожа. Вместо сообщения OrderRequest клиент отправляет (PUT) ресурс Order, и ресурс должен содержать всю ту же информацию, которая необходима для завершения транзакции. По общему признанию, если вы пытаетесь выполнить сложные оркестровки, вы можете обнаружить, что REST немного громоздкий по сравнению с SOAP, но это не значит, что вы не можете использовать REST для своего front-end, просто SOAP поможет вам лучше ваши внутренние службы.

Реальность, однако, заключается в том, что в 99% случаев людям не нужна сложность WS-транзакций. Я знаю это, потому что я использую SOAP (WCF) почти исключительно и редко использую WS-транзакции.

В REST состояние "находится" на клиенте. Сервер сообщает клиенту: "вот вся информация, которая вам нужна, чтобы дать мне создать этот ресурс (завершить эту транзакцию)". Но эта пустая форма фактически не начинает транзакцию. Это до клиента, чтобы фактически предоставить информацию - заполните форму, так сказать. То, что делает клиент при заполнении формы, не имеет отношения к серверу; когда клиент, наконец, отправляет готовую форму на сервер, он проверяется полностью. Это похоже на единицу работы, за исключением того, что клиент отслеживает "работу".

Надеемся, что это даст лучшее представление о том, как транзакции могут быть и достигнуты за REST. Они просто полагаются на более богатую концепцию сообщений/ресурсов и форму оптимистического concurrency.

Ответ 9

Потому что не каждая система требует транзакций.

Ответ 10

Я знаю очень успешные системы онлайн-учета (SaaS), у которых есть API-интерфейс, не основанный на REST, для создания, извлечения и обработки счетов-фактур и т.д. Они широко признаны за их API и простоту интеграции их системы с другими сторонами, API-интерфейс прост в обслуживании, можно использовать на разных платформах и обеспечить обратную совместимость достаточно прост.

Отсутствие транзакций может быть настоящей болью в шее, но большую часть времени, когда их серверы не слишком загружены, API работает очень хорошо.

Иногда, менее совершенный, достаточно хорош.