Maybe a little late to the conversation but thought I'd add my 2 cents. I'm 
in the middle of implementing a financial system on top of Cassandra (not 
my choice but in retrospect it's forced me into decisions that I think are 
better than if I had relied on an ACID-compliant database). 

First off - I'd highly highly recommend watching this video by Pat Helland 
(and reading his article posted by atomly above). Basically he was mentored 
by Jim Gray who defined ACID... has since become a thought leader in 
distributed systems arguing against attempting to force systems into a 
globally consistent state. But unlike many who argue that you don't need 
ACID anymore he describes how the guys who invented transactions did it to 
begin with, and how you can apply those same concepts to achieve the 
results you need as you fight with systems that are more and more 
disconnected and distant. 

The 2 things that have helped me tremendously have been:

   1. Open-nested transactions... Pat describes well in the video. 
   Basically it boils down to re-defining what you think of as "not happen at 
   all" in a rollback scenario. Rolled back transactions absolutely have 
   side-effects within ACID-compliant databases... but you just don't see the 
   effects of them, usually because it takes compensating action to clean it 
   up (to Victor's point above about the bank reversing the payment). Which 
   leads to point 2:
   2. Because the database controls the read model. You don't directly read 
   the datafiles, and so Oracle or SQL Server can write an internal log that 
   something has happened, allow your transaction to read it, but prevent 
   other transactions from reading it until you commit (sort of... other 
   transactions can still and often do use different isolation levels - so 
   even most ACID databases are more ACD most of the time). Rolling that back 
   doesn't really totally erase that data from existence. Again Pat Helland 
   describes internal data vs external data. Helped me tremendously. 

That 2nd point may be the bad news... if you can't control the read model 
of those transactions then you can't inject logic to suppress the read of 
data that hasn't been "committed". But that may be where Akka Persistence 
can help and doesn't need to replace your current data model. We do this in 
several places... internally we process and persist financial transactions 
using Akka Persistence journals which is the source of truth. As things 
complete and can be verified we publish many different views of that data 
externally - both within Cassandra and to a relational database for 
analysis/reporting. 

Here may be another consideration - yes it's possible that in the 
publishing of those views something may fail... however we don't want this 
to cause the other views to rollback. At this point it is in the Akka 
journal and is the official record - any failures in projecting that data 
externally will be retried and rolled forward until they succeed. They 
aren't invalid just because some external system wasn't available to ACK 
them. They are on the books and they must all eventually be delivered. We 
also use Akka to help manage this failure/retry. That model may not be an 
option for you in your use case, but look for ways to leverage structured 
logs and idempotency. Jonas Bonér has a great quote "Consistency is an 
island of safety, but so are idempotency and immutability". I think that 
might be from this talk https://www.youtube.com/watch?v=4OWwZa92qWw which 
is another great video to watch. 

Last thing - to your question about updating the account balance and 
inserting the records having to be in a single transaction... this is 
exactly the problem I had with working off of cassandra, which led us to 
relying on structured logs and akka persistence to begin with. The balance 
update is just a denormalization... the real data in that case is the 
insert of the record. This is reflected in the balance update only to make 
the read model of the balance more efficient (not having to read the 
journal of every record from the beginning of time). Also note this is a 
destructive write... not idempotent or immutable. I realize this probably 
wasn't the entire picture of your use-case, but you may want to consider 
adding complexity into your read model to allow handle this. If you don't 
need to denormalize the balance into a single field then that helps. 
Perhaps a read from the balance which also contains some log id or 
timestamp (be careful with timestamps though) of the last transaction that 
updated the balance... then before returning you check the records log for 
any later transactions that maybe haven't been reflected in the balance 
yet. So balance=700 as of transaction C, then transactions D=50 and E=50 
cause getCurrentBalance to return 800. Decoupling the read model and write 
model can be powerful (see Greg Young's CQRS thoughts and Nathan Marz 
Lambda Architecture). 

Apologies for the long post. It's a tough nut to crack and I've fought with 
it for the last 3 years. Akka absolutely helped me with this - hope those 
comments make some sense and give you some good ideas. 

On Thursday, May 12, 2016 at 11:41:24 PM UTC-4, kraythe wrote:
>
> I have a system that is a traditional DB centric app for the most part. 
> However the data is loaded in a memcache for speed and ease of use. What I 
> would be interested in doing is migrating the app to a actor centric 
> paradigm. Also keep in mind that I speak Scala but my colleagues don't so I 
> would have to be stuck in Java world. The use case I can't get past is this.
>
> A user has an entry in a competition and if they win the competition they 
> get a prize. When we want to award that user a prize we need to go update 
> the entry noting it has been paid, write multiple transactions to the 
> system to track the payment and update their wallet with the prize. Now all 
> of these things have to happen or none of them have to happen.
>
> It would make sense to make the entry an actor as well as the wallet. The 
> transactions are a bit more questionable. What I can't figure out is how I 
> can change all of those actors and fail if anything goes wrong. There is no 
> option to think that we can avoid ACID here. 
>
> I have been researching on google and this group and there is a lot of 
> information but most is dated and conflicting. Any ideas to help out?
>
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to