I have a comprehension question. I cannot understand how the database actions from the Neo4jTemplate like "getOrCreateNode()" belong to the surrounding transction. How is it implemented? The Neo4jTemplate would be shared in a multi-threaded environment? I cannot see a distinct membership of the transaction. I would understand if the actions are directly in the transaction object (e.g. tx.getOrCreateNode()).
#Service
public class TestService {
#Autowired
private Neo4jTemplate template;
public void save(IndexedTriple triple) {
GraphDatabase gdb = template.getGraphDatabase();
Transaction tx = gdb.beginTx();
Node subject = gdb.getOrCreateNode()
...
tx.success();
tx.finish();
}
}
Thanks in advance.
The below extract from the reference documentation pretty much sums it up. Use the spring transaction manager instead of using the Neo4j transactions and let spring take care of demarcation. Also, the transaction management is completely thread-safe. For you, I suggest using #Transactional annotation. If there is an existing transaction already, then spring joins that existing transaction as well.
Transactions
The Neo4jTemplate provides implicit transactions for some of its
methods. For instance save uses them. For other modifying operations
please provide Spring Transaction management using #Transactional or
the TransactionTemplate.
Related
For example I have #Stateless java bean:
#Stateless(mappedName = "test")
public class Test implements ITest
{
#Override
public void updateActivity
(SomeObj activity)
throws Exception
{
em.persist(activity);
}
}
Because it's a container-managed bean, then tell me, when does the container decide to synchronize the context with a DB? In this case I immediately see the results in the DB, but sometimes they do not seem to immediately appear there, right?
Please explain me How the synchronization works with the context and the DB at Container-Managed mode? When does the container decide to synchronize the context with a DB?
This will be driven by the transaction propagation configuration as your EJB bean might be one of many managed beans participating in a single transaction. This gets more complex if there are multiple transaction sources in flight e.g. XA 2PC. Generally, the changes will be flushed into the database on transaction commit however this further depends on the transaction isolation level or the presence of savepoints when nested transactions are used.
Check the #TransactionAttribute annotation docs or look for a tutorial that explains transaction propagation.
i'm working with spring jdbcTemplate in some desktop aplications.
i'm trying to rollback some database operations, but i don't know how can i manage the transaction with this object(JdbcTemplate). I'm doing multiple inserts and updates through a methods sequence. When any operation fails i need rollback all previous operations.
any idea?
Updated... i tried to use #Transactional, but the rolling back doesn't happend.
Do i need some previous configuration on my JdbcTemplate?
My Example:
#Transactional(rollingbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void Testing(){
jdbcTemplate.exec("Insert into table Acess_Level(IdLevel,Description) values(1,'Admin')");
jdbcTemplate.exec("Insert into table Acess_Level(IdLevel,Description) values(STRING,'Admin')");
}
The IdLevel is a NUMERIC parameter, so... in our second command will occur an exception. When i see the table in database, i can see the first insert... but, i think this operation should be roll back.
what is wrong?
JdbcTemplate doesn't handle transaction by itself. You should use a TransactionTemplate, or #Transactional annotations : with this, you can then group operations within a transaction, and rollback all operations in case of errors.
#Transactional
public void someMethod() {
jdbcTemplate.update(..)
}
In Spring private methods don't get proxied, so the annotation will not work. See this question: Does Spring #Transactional attribute work on a private method?.
Create a service and put #Transactional on the public methods that you want to be transactional. It would be more normal-looking Spring code to have simple DAO objects that each do one job and have several of them injected than it would to have a complicated DAO object that performed multiple SQL calls within its own transaction.
I've migrated from old style of transaction management with TransactionProxyFactoryBean to a Declarative transaction management recommended by Spring to avoid exceptions with transactions that appear from time to time.
For transactions save update delete I added the annotation:
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
It works good for me.
The question is:
Should I avoid using the annotation #Transactional when the transaction only reads data?
Example:
public TradeData getTrade(long tradeId) throws Exception {
return em.find(TradeData.class, tradeId);
}
After reading this article, which says:
"Better yet, just avoid using the #Transactional annotation altogether when doing read operations, as shown in Listing 10:"
I'm a little confused and I don't quite understand it.
For read-only operations with JDBC you don't need the #Transactional because it doesn't need a transaction, Hibernate does! So you can use #Transactional(readOnly = true). Then you are sure you don't update, delete, insert something by accident.
If a particular method of your service just read information from the database yes, you can put it as read-only
#Transactional(readOnly = true)
public Object yourReadOnlyMethod(){}
I am pretty new in Spring and in JPA and I am studying for Spring Core certification and I have some doubts about this question found on the study material:
Are you able to participate in a given transaction in Spring while
working with JPA?
I think that the answer is no because I know that JPA provides configuration options so Spring can manage transactions and the EntityManager but I am absolutly not sure to have correctly understand the question. What exactly means with participate in a given transaction.
At the beginning I interpreted as to interact with an existing transaction and this is impossible because a transaction is atomic for definition.
But them into the documentation I found this informations:
To transparently participate in Spring-driven transactions:
Simply use one of Spring’s FactoryBeans for building the
EntityManagerFactory
Inject an EntityManager reference with #PersistenceContext
Define a transaction manager: JpaTransactionManager
and show this example:
public class JpaOrderRepository implements OrderRepository {
private EntityManager entityManager;
#PersistenceContext
public void setEntityManager (EntityManager entityManager) {
this. entityManager = entityManager;
}
public Order findById(long orderId) {
return entityManager.find(Order.class, orderId);
}
}
So is it related to my original question? How?
What exatly do the #PersistenceContext annotation and what is the exact role of the EntityManager object?
Tnx
I am also learning for the certification and after reading your post I think this excerpt from Spring documentation is what this question is all about:
Spring JPA also allows a configured JpaTransactionManager to expose a
JPA transaction to JDBC access code that accesses the same DataSource,
provided that the registered JpaDialect supports retrieval of the
underlying JDBC Connection. Out of the box, Spring provides dialects
for the EclipseLink, Hibernate and OpenJPA JPA implementations. See
the next section for details on the JpaDialect mechanism.
also check What transaction manager should I use for JBDC template When using JPA ?
Considering there is no #PersistenceContext available to inject the EntityManager, plus you need to manually manage Transactions, what is the best way to design such an application?
For the EntityManagerFactory/EntityManager, as far as I can see, you must have each DAO accepting an EntityManager in the costructor e.g.
public class DAOImpl implements DAO
{
private EntityManager em;
DAOImpl(EntityManager em){
this.em = em;
}
//all CRUD operations follow
}
The first question that rises is when do you call EntityManager#close()?
Point A: The way I see it, you are better off doing this in a Filter at the end of the request cycle, which implies that you associate the EntityManager with the current thread (using ThreadLocal?)
Second question is, how and when do you inject the EntityManager?
Considering there is a ServletContextListener where we create and close the EntityManagerFactory, we could have a static method as follows
public static EntityManager createEntityManager(){
return entityManagerFactory.createEntityManager(PERSISTENT_NAME);
}
but since we want to encapsulate creating the DAO, we could use a factory e.g.
public class DAOFactory
{
public static DAO dao(){
//return a new DAO
}
}
As per Point A we should use a ThreadLocal to create the DAO using the EntityManager for the current Thread.
For managing Transactions.
The best way I can think of (which mimics the JPA spec) is to create your own Transaction annotation and use reflection to inject the begin/commit/rollback operations.
You should then return a Proxy from the DAOFactory which handles the transactions
I wouldn't do all that. Why try to recreate the whole JPA spec yourself? You just need to be able to use JPA without a container.
Spring can help you with this. Try it.