Defining the 2.X Platform Model in a Parallel Application

Developing a Play Framework 2.3.X app here using the Ebean ORM .

I just have doubts that I really want to clarify best practice when defining my models to make them "safe" in a parallel environment.

All my models suggested in the documentation are extensible play.db.ebean.Model

, and I have some instances that can be modified by various sources.

For example, I have this simple model, User

public class User extends Model {
@Id
public Long id;
public String name;
public String surname;
public String email;
public String password;
public int credits
}

      

who has some credits in his account. It can recharge them and it can get started and get work in the background that can destroy them. I blush when while simultaneously accessing / writing to a model there is a sensible choice to add

@Version
public Long version

      

for each instance to avoid inconsistent states in the model, and when this happens a value will be fetched OptimisticLockException

.

The question is, is annotation the @Version

best solution in an application like mine?

Is there a best practice I am missing that can be used to reduce the likelihood of getting it optimisticLockExceptions

, and if so, which ones?

Let's say optimisticLockExceptions

arises when making automatic payments by the system, for example, after paying by credit card, is it safe to cycle until the transaction completes successfully, thus not quitting optimisticLockExceptions

?

Should I add annotation @Version

to every model in my application?

Sorry for being so careful, but the model layer should be as robust as possible. Hoping that some of you can help me by answering even some of my questions.

Hello

+3


source to share


1 answer


Optimistic locking works like:

UPDATE TABLE_NAME SET fields = :new_fields, version = :old_version + 1 WHERE version = :old_version AND id = :id;

      

If nothing has been updated, it means that the object has been modified or deleted since the last read, so you need to redo the last transaction.



Optimistic locking is good when you have many database reads and few concurrent writes. But when you have a high concurrent write on the same object, you will end up with many optimisticLockExceptions

-> which you will be doing many rollbacks of transactions. For example, 10 concurrent writes on the same object can create up to 45 failed transactions and a total of 10 successful ones. Of course, in case of repeating the transaction until it succeeds. Its potential vulnerability: some "hackers" can execute multiple requests that perform concurrent updates for the same object. Therefore, I suggest limiting the repetitions to a reasonable count.

You need to add @Version

to all objects that need optimistic locking support. Of course, in case some type of object is only updated with another object that already contains @Version

, you cannot add it, but it can create errors in the future when this behavior changes.

+1


source







All Articles