First of all my question is What is the need of Transaction API in java ? Give me the practical example?
What is the meaning for Container Managed Transaction and Bean Managed Transaction?
And Difference between Declarative Transaction and Programmatic Transaction?
Please help me
Thanks in advance
Declarative transaction: you put the transaction declarative in the method declaration. so you doesn't need to implement the transaction manually. Here I give you the example:
// declarative
#Transcational
public void Transfer (Account from, Account destination, double amount) {
//do your logic here
}
// programmatic
public void Transfer (Account from, Account destination, double amount) {
var session = sessionFactory.openSession();
var tx = session.BeginTransaction();
try {
//do you logic here
tx.Commit();
} catch {
tx.Rolback();
}
}
Container managed transaction and bean managed transaction, i guess you are referring to Enterprise JavaBean? From my understanding, container managed transaction will not require the developer to explicitly write codes or constructs to manage the transaction, analogous to auto-commits for database.
Related
How can I turn off auto commit and give explicit commit using #transactional?
I have multiple operations and I want them to get committed after all select and update are done. Reason being the select is done based on some field as null and this data is used somewhere and then update is done to some records. So before new records come, I have to change the field as to some value and avoid selection of new data i.e select only those record that got updated
You just need to put the #Transaction annotation around all the work you want to be committed:
#Autowired
private Manager1 manager1;
#Autowired
private Manager2 manager2;
#Transactional
public void doStuff() {
manager1.do();
manager2.do();
}
Everything in method doStuff() will all be committed together, unless there is an exception thrown, in which case it will all be rolled back.
I would recommend you to use Programmatic approach for this case.
Programmatic transaction management: This means that you have manage the transaction with the help of programming. That gives you extreme flexibility, but it is difficult to maintain.
Vs
Declarative transaction management: This means you separate transaction management from the business code. You only use annotations or XML based configuration to manage the transactions.
Perhaps, alternative way for your questions by Programmatic transaction management.
Eg.
/** DataSourceTransactionManager */
#Autowired
private PlatformTransactionManager txManager;
public void yourMethod() {
try {
// Start a manual transaction.
TransactionStatus status = getTransactionStatus();
your code...
.....
.....
//your condition
txManager.commit(status);
//your condition
txManager.rollback(status);
} catch (YourException e) {
//your condition
txManager.rollback(status);
}
}
/**
* getTransactionStatus
*
* #return TransactionStatus
*/
private TransactionStatus getTransactionStatus() {
DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
dtd.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
dtd.setReadOnly(false);
return txManager.getTransaction(dtd);
}
Note: It does not mean you need to always use one approach like Programmatic transaction management. I prefer mixed approach. Please use easy way like Declarative transaction for simple database services, otherwise, just control with Programmatic transaction in your services will save your logic easily.
So far we have been using Hibernate alone - I am moving to JPA. Spring is used for MVC in our projects. They are used completely separately.
I checked the new Spring 4.0 Petclinic project with Hibernate JPA implementation (https://github.com/SpringSource/spring-petclinic.git). Again I do not see that influence of Spring on the Hibernate code. For example JpaPetRepositoryImpl is used without Spring except the #Repository annotation. Have I missed something?
The whole point of Spring is to be as unintrusive to your code as possible, you should see as little of spring as possible in your code. Basically that is the whole point and aim of Spring.
When you normally use hibernate without spring you would have some kind of singleton which constructs the hibernate SessionFactory.
public class HibernateUtil {
private static SessionFactory sf;
static {
sf = ew Configuration().configure().buildSessionFactory();
}
public static getSessionFactory() {
return sf;
}
}
The next thing you would see is code that is filling up with calls to HibernateUtils.getSesionFactory(). You would manually need to create your Session and start/commit transactions.
public void save(Entity e) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
try {
session.save(e);
tx.commit();
} catch (HIbernateException he) {
tx.rollback();
} finally {
session.close();
}
}
However this code is bad due to 2 reasons. The first you are manually managing your transactions, which after a while becomes a pain, you want to use declarative transaction management. The second you are managing transactions at the wrong layer, transactions should be managed at the service layer. Now to make that possible you would have to get the SessionFactory in your Service layer, which would suddenly turns data access layer into a leaky abstraction.
Spring can help you with both things, it can do declarative tx management and hide the fact that you are using Hibernate, not making it a leaky abstraction.
#Inject
private SessionFactory sf;
public void save(Entity e) {
sf.getCurrentSession().save(e);
}
This would be the same in a Spring way. The transaction would be started at the service level (with a #Transactional or #TransactionAttributes annotation).
For JPA this is more or less the same, however as JPA is a standard Spring tries to follow those as much as possible. So plain JPA code and JPA code in Spring doesn't differ that much (unless you are using JPA in a standalone application and not a JEE container, than the JPA code would be like the hibernate code).
one of the big advantages is declarative transaction management using #Transactional annotation, where Spring manages the transaction commit/rollback, have a look at this example.
I like the #PersistenceContext annotation that injects an EntityManager into my Spring beans. If you are familiar with the SoC ideology, it makes everything a lot clearer to use Spring, but some find it confusing and too magic I guess.
I for sure would totally advise you against using hibernate/jpa/persistence manually without any IoC framework.
Spring with declarative transactions requires proxies or byte code transformations. It complicates debugging and slows down application startup time. There are many ways to avoid this complexity, one of ways is Command Design pattern:
public class Transaction {
public void execute(Command command) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
try{
Transaction tx = session.beginTransaction();
try {
command.execute(session);
tx.commit();
} catch (HIbernateException he) {
tx.rollback();
}
}finally{
session.close();
}
}
}
Probably you will need "Context" parameter instead of "Session" for "command.execute(context)" to abstract this design in practice but for example it is more clear to have "Session" parameter.
Multiple commands can be executed in the same transaction using composite command wrapper. This design pattern can be used to add command validation, security: "command.isValid(context)", "command.checkPermissions(context)". Many other aspects can be implemented by this simple but powerful design pattern without dependency on any heavy weight frameworks. You can use this design with Spring too, Spring is fine to configure factories in XML but I think Spring is too heavy weight and it is too complicated for other use cases.
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.
I am trying to create a testcase for my DAO classes that use plain Hibernate API (no Spring stuff like HibernateTemplate,HibernateDaoSupport), just like this:
sessionFactory.getCurrentSession().save(obj);
I have the appropriate sessionFactory and transactionManager definition in spring context as shown in the spring docs.
What I want is to open a transaction in my start up code and rollback at the end.
So this is different from the default Spring unit testing supporting concept of transaction for every test method call and so I could not extend AbstractTransactionalTestNGSpringContextTests.
I need a way to start a transaction and somehow feed it in session factory. I feel this should be extremely easy but could not achieve after lot of reading and experiments.
Any help would be greatly appreciated.
If you don't want to use HibernateTemplate, you can use transactionManager directly as described in 10.6.2 Using the PlatformTransactionManager.
try {
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
...
tx.commit();
session.close();
} catch (SomeException e) {
tx.rollback();
...
}
#Transactional(readOnly = false, propagation = Propagation.REQUIRED)
annotate the test method using above
In my code I am updating two table, one after the other.
update(table1_details);
update(table2_details);
So if the update fails in table1 , table2 should not be updated or should be rolled back.
How to handle this situation. I know I have to use transaction. Can some one help with code !!!
I am using Java with spring and hibernate .
The question is a bit broad and there are several ways to implement this but I would:
Use Spring to inject Hibernate SessionFactory into DAOs objects.
Use Spring to inject DAOs in a service object and call them inside a business method.
Use Spring declarative transaction management at the business method level (either with Spring AOP or #Transactional).
Something like this:
#Transactional
public void doSomething() {
dao1.foo();
dao2.bar();
}
For more details on the configuration, check the Chapter 9. Transaction management of the Spring documentation.
I can't recall the correct api, but something like this:
Transaction tx = em.getTransaction();
tx.begin();
try {
update1(); update2();
}
catch(Exception e) {
failed = true
}
finally {
if( !failed ) tx.commit();
else tx.rollbacl();
}