One of the things I’m currently playing with is creating a durable Stm, functionality is going to be integrated in the main Stm implementation of the Multiverse STM. I’m doing a poc to figure out what kind of interfaces and changes the Multiverse STM is going to need.
The idea is that persistence for a lot of enterprisy applications I have seen just didn’t feel very comfortable:
- dealing with proxies; so problematic self calls in services and identity problems on entities
- dealing with or mapping
- dealing with setting up the db and creating ddl
- not being able to do dependency injection on entities
- objects getting an id once they are going to commit and not before
It takes up too much time and since STM already manages states of your objects, adding a storage-engine
behind is not that strange. To give you an idea how simple it could be, lets create a small Bank example:
@TransactionalObject
class Customer{
private final String id;
public Customer(String id){
return id;
}
public String getId(){
return name;
}
}
@TransactionalObject
class Account{
private final Customer customer;
private int balance;
public Account(Customer customer){
this.customer = customer;
}
public Customer getCustomer(){
return customer;
}
public int getBalance(){
return balance;
}
public void setBalance(int newBalance){
if(newBalance<0){
throw new NotEnoughMoneyException();
}
this.balance = newBalance;
}
}
@TransactionalObject
class Bank{
private final TransactionalMap customers =
new TransactionalHashMap();
private final TransactionalMap accounts =
new TransactionalHashMap();
public Account find(String id){
Account account = accounts.get(id);
if(account == null){
throw new AccountNotFoundException();
}
return account;
}
public void transfer(String fromId, String toId, int amount){
if(amount<0){
throw new IllegalArgumentException();
}
Account from = find(fromId);
Account to = find(fromId);
to.setBalance(to.getBalance()+amount);
from.setBalance(from.getBalance()-amount);
}
public Customer createCustomer(){
Customer customer = new Customer();
customers.put(customer.getId(),customer);
return customer;
}
public Accoount createAccount(Customer customer){
Account found = accounts.get(customer.getId());
if(found!=null){
throw new AccountAlreadyExists();
}
Account newAccount = new Account(customer);
accounts.put(customer.getId(), newAccount);
return newAccount;
}
}
And you could wire it up in Spring like this:
<bean id="bank" class="DurableTransactionalObjectFactoryBean">
<property name="id" value="bank">
<property name="class" value="Bank">
</bean>
And use this bean in your controllers for example. The DurableTransactionalObjectFactory will create or load a durable transactional object with the given id from disk.
As you can see there is:
- no or-mapping needed
- no dao’s needed
- no fuss with transaction configuration
- no need for rolling back state on objects manually, check the tranfer function where the setBalance on the from could thrown a NotEnoughMoneyException and normally could leave the to account in an illegal state
All operations on the bank are executed in full ACID nature.
I hope I’m able to add a experimental storage engine to Multiverse 0.6 (planned in 3 months) so I can learn more about what I’m going to need and what the exact semantics need to be for durable/non-durable objects and about their lifecycles.
Posted by pveentjer