Search:

Search all manuals
Search this manual
Manual
Couchbase Developer's Guide 2.0
Community Wiki and Resources
Download Couchbase Server 2.0
Couchbase Server 2.0 Manual
Client Libraries
Couchbase Server Forum
Additional Resources
Community Wiki
Community Forums
Couchbase SDKs
Parent Section
7.4 Providing Transactional Logic
Chapter Sections
Chapters

7.4.1. Using a 'Lease-Out' Pattern

When you use this web application pattern, you 'lease-out' information, or in other words, reserve a document for use by a single process. By doing so, you manage any conflicts with any other processes that my attempt to access the document. Imagine you want to build an online ticketing system that meets the following rules:

To fulfill these requirements, we can use these techniques:

The process would look like this if follow the basic application flow:

Figure 7.1. Ticketing System

Ticketing System

The initial stage of our ticket document, as JSON, would appear as follows:

{
	"ticket_id" : "ticket1",
	"seat_no" : 100,
	"state" : "AVAILABLE"
}

The ticket document has an unique id, an associated seat, and an explicit state field to store that state of our ticket transaction. We can use this information in our application logic to ensure no other process tries to reserve the seat. We can also use this information to roll-back the ticket to an initial state. Imagine a user searches for open seats, and then they want a seat that is unavailable. Our system can get all the tickets that were requested but not purchased by other users; these will all be tickets with expired leases. So we can also use this information to reserve seats and return seats to a pool of available seats that we offer to users. If a user selects a open seat, we put the ticket in their shopping cart, and indicate this in the ticket document:

{
	"ticket_id" : "ticket1",
	"seat_no" : 100,
	"state" : "INCART",
	"expiry" : <timestamp>
}

Notice that when we update the state of the ticket, we also provide an expiration. The expiry in this case is 5 minutes, and serves as the lease, or time hold that is in place on the ticket so that no other processes can modify it during that period. The user now has 5 minutes to pay for the ticket. If a user moves forward with the purchase, our application should then get each ticket in the user cart from Couchbase Server and test that the tickets in the user shopping cart have not expired. If the ticket lease has not expired, we update the state to PRE-AUTHORIZE:

{
	"ticket_id" : "ticket1",
	"seat_no" : 100,
	"state" : "PRE-AUTHORIZE",
	"expiry" : <updated_timestamp>
}

Note at this phase we also update the timestamps to 5 minutes once again; this provides the additional time we may need to authorize payment from a credit card, or get an electronic payment for the ticket. If the payment fails, for instance the credit card is not authorized, we can reset the tickets to the state AVAILABLE. Our system will know that the ticket can be returned to the pool of available tickets that we present to users. If the payment succeeds, we then set the ticket state to SOLD and set the expiration to 0:

{
	"ticket_id" : "ticket1",
	"seat_no" : 100,
	"state" : "SOLD",
	"expiry" : 0
}

So we set the expiration explicitly to 0 to indicate the ticket has no expiration since it is sold. We keep the document in the system so that the user can print it out, and as a record until the actual event is over. Here is the process once again, this time we also demonstrate the state changes which keep track of the ticket along with the application flow:

Figure 7.2. Ticket Document Updates

Ticket Document Updates

This diagram shows some of the compensation mechanisms we can put in place. If the seat that a user selects is not AVAILABLE we can reset all the tickets that are expired to AVAILABLE and retrieve them for the user. If the user fails to complete the checkout, for instance their credit card does not clear, we can also reset that ticket state to AVAILABLE so that it is ready to retrieve for other users. At each phase of the user interaction, we keep track of the ticket state so that it is reserved for checkout and payment. If the system fails and the ticket is persisted, we can retrieve that state and return the user to the latest step in the purchase they had achieved. Also by preserving the ticket state and expiration, we withhold it from access and changes by other users during the payment process.

An alternate approach you can use with this same pattern is to have a ticketing system that offers a fixed number of general admission tickets. In this case, we can use lazy expiration in Couchbase Server to remove all the tickets once the event has already passed.