REST TCC事务能否处理PUT请求?附业务场景需求
Great question! The short answer is: Yes, REST-based TCC (Try/Confirm/Cancel) absolutely can handle PUT requests—you just need to map the TCC workflow phases to RESTful semantics in a way that aligns with state-modifying operations like adjusting stock counts. Most TCC examples focus on POST/DELETE for reservations/cancellations, but PUT fits perfectly here because of its idempotent nature, which is critical for reliable distributed workflows.
Let’s walk through your stock update example (adding 1 to a stock count, with rollback if another service like Shipment fails) to see how this works:
1. Try Phase: Reserve & Validate
The Try phase is all about locking in resources or validating that the operation can succeed, without making permanent changes. For stock updates, you can use a PUT to create a temporary reservation state:
- Send a
PUT /stock/{itemId}/reserverequest with a body like{"delta": +1, "transactionId": "shipment-123"}. - The Stock service checks if there’s enough available stock to cover the delta, then creates a reservation record tied to your transaction ID. It might also adjust a "reserved stock" field (e.g.,
reservedCount: 1) while leaving the actualavailableCountuntouched for now. - Since PUT is idempotent, if the client retries this request (due to network blips), it won’t create duplicate reservations—you can just revalidate the existing reservation for the transaction ID.
2. Confirm Phase: Commit the Permanent Change
Once all services (like Shipment) have successfully completed their Try phases, you confirm the stock update with another PUT:
- Option 1: Send a
PUT /stock/{itemId}with the final desired state:{"availableCount": originalCount + 1, "reservedCount": 0}(clearing the reservation and updating the actual stock). - Option 2: Use a dedicated endpoint to confirm the reservation:
PUT /stock/{itemId}/reserve/{transactionId}/confirm. This tells the Stock service to apply the reserved delta to the actual available count and delete the reservation record. - Either way, this PUT commits the change permanently—after this step, the stock count is finalized.
3. Cancel Phase: Rollback the Reservation
If any service fails (e.g., Stock’s Try phase failed, or Shipment’s update went wrong), you cancel the reservation using a PUT (or even DELETE, but PUT works well for state reversal):
- Send a
PUT /stock/{itemId}/reserve/{transactionId}/cancelwith a body that triggers releasing the reserved stock. The service would revert thereservedCountto 0 and ensureavailableCountgoes back to its pre-Try value. - Again, PUT’s idempotency means retrying this cancel request won’t cause issues—if the reservation was already cleared, the service just returns a success without side effects.
Critical Best Practices for REST TCC with PUT
- Idempotency First: Always design your PUT endpoints to be idempotent. Use transaction IDs or unique identifiers to track reservations, so retries don’t create duplicate state changes.
- Separate Temporary & Permanent State: Don’t mix reserved (Try) and committed (Confirm) state in the main resource unless you have clear flags (like
reservedCountvsavailableCount). This avoids confusion and makes rollbacks cleaner. - Versioning/ETags: Include ETags or resource versions in your PUT requests to prevent concurrent modification issues. For example, if another transaction modified the stock while your reservation was active, you can detect the conflict and handle it appropriately.
Remember: TCC is about business logic phases, not specific HTTP methods. PUT is ideal here because it’s designed for updating resource states—exactly what you need to reserve, commit, or roll back changes to stock counts.
内容的提问来源于stack exchange,提问作者Ethan

