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.