According to this link: EF Code First DBContext and Transactions
I should wrap the savechanges in a TransactionScope using statement.
I thought the SaveChanges works like or is a transactional method.
Example:
In a service method I am deleting and adding different entities in one http request at the end of the service method I do a SaveChanges one ONE Context.
I will have never multiple context. Its always the same context inject by Ninject created for the lifetime of a http request and shared among the repositories.
So is it true that I only need to wrap tehe DbContext.SAveChanges in a TransactionScope when I have multiple dbcontext ? - because these could be multiple databases aka a distributed transaction - ?
It is not necessary to wrap your SaveChanges call in another TransactionScope if;
If you are not trying to use multiple context in the same transaction.
If you are not making multiple SaveChanges calls even with the same context. For instance, one SaveChanges after Delete, another SaveChanges after add...
In summary, you can do multiple delete/add operations with the same context, and call the SaveChanges method once in the end - they will all be applied in one transaction. TransactionScope is only necessary if you have nested transaction scenarios.
Related
When I use the AddRange method from the Entity Framework and then call SaveChanges, if one of the Entities fails to be inserted into the DB, will everything be rollbacked?
I don't want to use explicit Transactions.
From msdn doc:
SaveChanges operates within a transaction. SaveChanges will roll back that transaction and throw an exception if any of the dirty ObjectStateEntry objects cannot be persisted.
https://msdn.microsoft.com/en-us/library/bb336792(v=vs.110).aspx
I hope it helps!
Right now I have to call JPA merge() at the end of my service method to persist changes. I'm doing this because our servlets do not start a transaction before the Locator.find() runs. They start them later in the service method.
I know that RequestFactory uses my Locator find() and updates the object based on what the client sent to the server, so I was just wondering if maybe that object should be an attached object and therefore allow JPA to handle the changes "naturally" rather than explicitly call merge().
Or perhaps this just depends on the situation?
I don't know JPA much, but I confirm that you SHOULD scope your transactions to your service methods: a RequestContext is a batch of requests that can each succeed or fail independently, putting them all in a single transactions would violates that principle. There are also cases where your Localor#find can be called, changes applied to the entity, but then the entity is never passed to any service method: you wouldn't want the changes to be persisted in this case.
The JPA 2.0 specification talks about the PrePersist and PreRemove callbacks on page 95:
The PrePersist and PreRemove callback methods are invoked for a given
entity before the respective EntityManager persist and remove
operations for that entity are executed. For entities to which the
merge operation has been applied and causes the creation of newly
managed instances, the PrePersist callback methods will be invoked for
the managed instance after the entity state has been copied to it.
These PrePersist and PreRemove callbacks will also be invoked on all
entities to which these operations are cascaded. The PrePersist and
PreRemove methods will always be invoked as part of the synchronous
persist, merge, and remove operations.
My mother tongue is not English, so I may misunderstand what would be quite clear for another dude. Or the quote could use a clarification or two. But I fail to understand:
Will the PrePersist and PreRemove callback be called only once per life time of a running Java EE application?
If the callbacks are fully synchronized with calls to EntityManager#persist(java.lang.Object) and EntityManager#remove(java.lang.Object), then yes I expect the callbacks to be fired only once. I usually don't persist my entities more than once, nor do I delete them over and over again just for the fun of it. Alas this is "just" my reasoning.
But! Say you have code that shall persist one entity at the beginning of a new transaction, then within the same transaction you hook the entity up with some new and non persisted entities. It would be intuitive and certainly not wrong to provoke a cascading persist operation on all those relationships with a secondary smooth call to EntityManager#persist on the owning entity before the transaction commit. In that case.. would the PrePersist callback be called again, a secondary time?
In my application I need most objects fetched in detached mode (fetched with the find API).
I'm wondering if there is a way to ask a detached object from the JPA provider and save the extra call to detach() API.
In additional I would expect the object created in such mode to be less expensive since the JPA provider doesn't need to add it to the entity manager context.
Is there a way to achieve this with JPA APIs?
Is there a way to achieve such functionality with query results?
Specifically I'm using Eclipse Link so if there is a specific way to do it with this implementation it will be helpful as well.
You can fetch a detached entity without an extra call to detach() if you fetch it outside a transaction. If you are not using container-managed transactions, it's trivial, simply do not start a transaction.
If you are using CMT, you have to make sure the requesting object is not a transaction-enabled EJB:
if in an EJB, suspend the transaction by annotating the appropriate method with:#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED),
or
call the EntityManager from a POJO. You dont have to call it directly, it only impotrant that the query result will end in a non-EJB object.
AFAIK, there is no performance gain to be expected, since the query result will always be put in the current persistence context, however shortlived it may be.
EDIT: There is another possibility to get detached objects which does not depend on transaction demarcations: JPA constructor expressions:
List<DTO> dtos = em.createQuery("SELECT NEW com.example.DTO( o.title, o.version) FROM Entity o").getResultList();
The constructed type must have a constructor with all the relevant attributes. The objects in the list, entities or not, will always be created detached. However there is a small overhead of instantiating a new object.
Is there a way to implement transactions in code first without having to write stored procedures?
I have some scenarios where multi-table entries need to be created with unique guids before a final table entry can be created. Is this something I can code using EF alone?
DbContext.SaveChanges() method uses a transaction . So it is Atomic and you don't want to use stored procedures. The unitOfWork patter is implemented in EF itself to accomplish this.
But let's say you are using two DbContext instances to d your job , then you need to wrap your work with a transaction scope like this,
using (var scpe=new TransactionScope()){
...
context1.SaveChanges();
....
context.SaveChanges();
scope.Complete();
}
SaveChanges operates within a transaction. SaveChanges will roll back
that transaction and throw an exception if any of the dirty
ObjectStateEntry objects cannot be persisted.
See the documentation