Making the user work with a Transaction API even though the storage doesn't implement it "at all" isn't a novelty of OGM. Remember MySQL's MyISAM ? It's supported by Hibernate, and while InnoDB might be on the rise compared to MyISAM, it's not dead.
The range of transactional capabilities of different engines varies a lot in many subtle details which are hard to classify under a single standard API; In my view not supporting any transactional capability is just a very low form of transaction capabilities :) I would totally agree with you that this is a concrete and interesting problem to solve, but I don't think it's something for OGM to do. Sanne On 6 May 2015 at 10:31, Gunnar Morling <gun...@hibernate.org> wrote: > 2015-05-06 11:13 GMT+02:00 Sanne Grinovero <sa...@hibernate.org>: >> >> Did you consider that the existing definition of "Transaction >> boundaries" can have different levels of isolation and guarantees, >> depending on how the underlying components are configured? > > > I didn't, but that's exactly the point. Talking (API-wise) about > "transactions", "isolation levels" does not really make sense if the > underlying backend is non-transactional by its nature. > > We just piggy-back on the transaction cycle from ORM to control flushes, but > this doesn't give you any sort of transactional guarantees if not natively > supported. If you e.g. do an explicit flush() in the middle of a > "transaction", these changes will be visible to other clients, no matter > what kind of isolation level has been configured somewhere. > >> I do agree with you that it's kind of weird that people write code >> without making transactional requirements explicit in the code, but it >> seems that the trend is to abstract from that and use the >> "Transaction" term as a "Unit of work". > > > Where do you see this trend? Surely not e.g. in MongoDB or CouchDB? It's > exactly the usage of the term "transaction" which I find irritating for > these stores and which I thus seek to avoid. > >> For example I find it strange that - in Java - one has to configure >> the isolation levels of transactions to the safest (least efficient) >> option possible among the types his *various* use cases require. It's >> pretty obvious that it would be more efficient to choose those levels >> as "profiles" based on use case, possibly bean or even method level. >> I guess that's were complex applications split up in multiple >> deployments.. >> >> What is concerning is that the average developer will write Java code >> making assumptions on the underlying transaction guarantees, and will >> rarely communicate those as requirements to whoever configures it. >> Is that what you aim to solve? >> > Not really. What I aim to solve is to avoid making the user work with APIs > which suggest certain kinds of guarantees which in reality are not there for > certain backends. >> >> >> >> >> On 6 May 2015 at 10:01, Gunnar Morling <gun...@hibernate.org> wrote: >> > Hi, >> > >> > When talking to people about OGM, there is always that awkward moment >> > when >> > you need to explain that TX demarcation is required also for >> > non-transactional data stores. >> > >> > While it makes sense for our purposes (we use the "TX cycle" to optimise >> > the work sent to the backend etc.), I can understand people who find >> > that >> > odd API-wise. So I was thinking about how this could be improved. >> > >> > When it comes to CDI, a more "neutral" annotation (and a portable >> > extension >> > examining it) than @Transactional could be helpful: >> > >> > @UnitOfWork >> > public void saveOrderAndCustomer(Order order, Customer customer) { >> > session.persist( order ); >> > session.persist( customer ); >> > } >> > >> > By means of the @UnitOfWork annotation it would be expressed that the >> > entire method should run as one "transaction". This also could be used >> > to >> > specify an error handler for our new API to be applied for this unit of >> > work: >> > >> > @UnitOfWork(errorHandler=FailedOpsLoggingHandler.class) >> > public void saveOrderAndCustomer(Order order, Customer customer) { >> > ... } >> > >> > In non-managed environments, Java-8-style Lambda expressions could be >> > leveraged nicely to achieve the same: >> > >> > session.runUnitOfWork( () -> { >> > session.persist( order ); >> > session.persist( customer ); >> > }; >> > >> > This should feel much nicer to e.g. users of the MongoDB backend than >> > invoking session.getTransaction().begin()/commit(). It also plays >> > greatly >> > together with the error handling stuff: >> > >> > session.buildUnitOfWork( () -> { >> > session.persist( order ); >> > session.persist( customer ); >> > } ) >> > .onFailedGridDialectOperation( context -> { >> > // e.g. log failed op >> > return ErrorHandlingStrategy.ABORT; >> > } ) >> > .onRollback( context -> { >> > // e.g. log applied ops >> > } ) >> > .run(); >> > >> > Of course something equivalent could be done for Java 7, but it'd >> > probably >> > look not as concise. >> > >> > Any thoughts? >> > >> > Cheers, >> > >> > --Gunnar >> > _______________________________________________ >> > hibernate-dev mailing list >> > hibernate-dev@lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev