> > Simply put if there's $5 left in the bank, you wouldn't want to have > > a user withdraw $5 with two different web browsers if they hit > > submit at the same time... so we kinda want it to be like there's > > only one teller window, and the servlets have to wait their > > turn.
A poster already mentioned that simplistic solutions might not work in a clustered environment. I agree that designs that work due to timing or happen stance that may not remain constant are weak designs bound to have problems in deployment. This problem is the the classic stale update scenario. Multiple clients show $5 available to with draw. They all hit "submit" at once. How to guard against an over draft in a robust and repeatable in all scenarios way?? The most offered solution that I've heard and I've implemented uses optimistic concurrancy guarded with a row version number; - add a version number or modification date to your data base tables. I use a sequence number that trigger auto-increaments on update. - Your Model class (represents a data base table row) returned by DAO's and Entities include the sequence number. - Your presentation tier has a reference of the model (including the row version number) and all display $5 and internally held in the session is an instance of the Model used to generate the dynamic data by your View (MVC) component. - All users hit submit. - The Controller (MVC) processing this event fetches the Model from the session and calls the setter to modify withdraw ammount, passes this Model to the Business Deligate to access your transactional layer (mediated by a Session bean calling Entities). - The Model instance is serialized and passed as an argument to the layers of business components down to the Entity responsible for updating the AccountBalance table row for this account. - I used BMP and DAO objects to package the SQL logic. My DAO fetches the sequence number from the Model and account new balance from the model and builds the SQL prepared statement: UPDATE account set balance = ? where column_version_num = ? ; I call stment.setString (1, model.getNewBalance()); stment.setString (2, model.getVersionNumber()); If I get a SQLException on this update, then I know that someone else beat me to the $5. The key concept is the WHERE clause will only update the row IFF the sequence number has not been changed by someone else (meaning I had stale data). This will work in clustered environments at all times and does not depend on synchronized business delegate methods or any other design that is likely to be defeated by appserver servlet or object pooling or use of multiple VMs to host your application. Good luck, curt