using programmatic transaction control in CMT bean - java

I need to commit transactions from CMT bean by hand. There is a loop which processes multiple records and each record should be processed in its own transaction. I wanted to mark method transaction support as NOT_SUPPORTED and then control transaction from method. However I could not retrieve a UserTransaction instance neither from SessionContext neither injecting it as a JNDI resource java:/module/UserTransaction.
Are there any chance to process multiple records in CMT bean in their own transactions without introducing new BMT bean for such processing?

You should not mess around transactions yourself if you use CMT.
I recommend you create a method for the operation needs to be in transaction, mark it as REQUIRES_NEW, then call it from the loop.
Everytime the method is called, the current transaction (if any) will be suspended and a new transaction will be started for the operation.
Something like this:
#EJB
SomeEJBLocal anotherme;
public void loop() {
for(/* something */) {
anotherme.single();
}
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void single() {
// do stuff
}
You will have to inject another instance of the EJB and call single in order for the container to process the transaction aspects.

Related

Will an EntityManager with context type TRANSACTION in a Singleton join an external bean-managed transaction?

Suppose I have a Singleton bean with an EntityManager in it. The singleton also specifies (on method or class level) a transaction attribute REQUIRED. The entity manager is obtained via an #PersistenceContext injection which specifies persistence context type TRANSACTION. For all intents and purposes, if a method on this singleton is invoked with an existing transaction, the entity manager should join the transaction or possibly provide an already existing one linked to that transaction via proxy. If such a method is invoked outside of a transaction a new transaction will be started for the duration of the method invocation.
Now suppose we have a second bean which uses bean-managed transactions and injects the singleton. If it explicitly starts a user transaction and then invokes a method on the singleton, will the entity manager in that method join that user transaction? Will the jump from bean-managed to container-managed transaction context even work? I know the other way around doesn't and forms a barrier.
The singleton class:
#Singleton
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class PersistenceSingleton {
#PersistenceContext(unitName = "test", type = PersistenceContextType.TRANSACTION)
private EntityManager em;
public void doStuff() {
// perform actions with the entity manager that imply changes in the database
}
}
The bean with user transactions (might as well be stateless or stateful):
#Singleton
#TransactionManagement(TransactionManagementType.BEAN)
public class PersistenceFacade {
#EJB
private PeristenceSingleton ps;
#Resource
private UserTransaction userTx;
public void doStuff() {
userTx.begin();
ps.doStuff();
userTx.commit();
}
}
Does the transaction started in method doStuff() of the PersistenceFacade get taken into account when invoking doStuff() on the PersistenceSingleton? Does the entity manager automatically join the transaction and behave as expected from transaction isolation during concurrent access?
UserTransaction is used for changing the default transaction demarcation but we still control the JTA transactions.
https://www.javacodegeeks.com/2013/03/types-of-entity-managers-application-managed-entitymanager.html says:
If you have UserTransaction you can start demarcating what is to be executed within the transaction. Notice that you’re still controlling
the JTA transactions
so The persistence context propagation rule will be applied for UserTransaction demarcation.
pro JPA book says:
When a method is invoked on the transaction-scoped entity manager, it
must first see whether there is a propagated persistence context. If
one exists, the entity manager uses this persistence context to carry
out the operation. All subsequent transaction-scoped entity manager
operations, in this component or any other, will thereafter use this
newly created persistence context. This behavior works independently
of whether container-managed or bean-managed transaction demarcation
has been used.
the answer to your questions is yes(first question)
Does the entity manager automatically join the transaction and behave
as expected from transaction isolation during concurrent access?
entity manager checks the existence of a propagated persistence context and uses it.

Jboss EAP 7 CDI JTA #Transactional

I am struggling to understand how I am supposed to deal with JTA and CDI running on a Jboss EAP 7 instance. I can get a transaction manually by injecting a UserTransaction object coming from the container but when I annotate the method with the #Transactional I get an exception regarding no transaction available.... My question is. Is there any config missing? I read briefly that maybe I should create an interceptor myself in order to make it work, but I haven't found any consistent example...
In a default JEE container-managed environment, only enterprise beans (usually #Stateless beans are used) are transactional. Once you enter such a bean from outside, the transaction will be opened. With the #javax.transaction.Transactional annotation you can control the behavior of the transactions, but this is not necessary in default case.
Example bean:
#Stateless
public MyBean {
public void withinTransaction() {
System.out.println("i'm running within a transaction");
}
#Transactional(TxType.NOT_SUPPORTED)
public void outsideTransaction() {
System.out.println("no transaction available...");
}
}
If you call MyBean.withinTransaction from a Servlet (e.g. via REST), a new transaction is created (if not already present).
If you call MyBean.outsideTransaction, no transaction will be created.
If you call this.outsideTransaction() from withinTransaction, you will still have the transaction available in outsideTransaction (because the interceptors are only bound to the bean boundaries)
If you call this.withinTransaction() from outsideTransaction no new transaction is created (because the interceptors are only bound to the bean boundaries)
If outsideTransaction would be part of a second bean AnotherBean, which #Injects MyBean, and you call MyBean.withinTransaction, then a new transaction will be created (if not already present). Because you cross bean boundaries between AnotherBean.outsideTransaction and MyBean.withinTransaction.

Does Spring MVC issue a commit after calling SpringStoredProcedure.execute()

Does Spring issue a commit to the database after each package call, or does it only commit after everything is done?
I am using Spring and Struts. In my controller class, I am calling many database packages with spring stored procedure in a DAO class. each call has its only method in the DAO class
My question is, will Spring commit only after all calls have been made from the controller class and the controller has finished, or will it commit after each execution of a SpringStoredProcedure?
my_package_getusers = SpringStoredProcedure.getStoredProcedureCompiled(getJdbcTemplate()
....
my_package_getusers.execute(params).get("result")
Spring utility classes from spring-jdbc don't make any commits. The responsibility for commiting transaction belongs to the spring-tx (transaction support.
This is usually made by placing #Transactional annotation on the method that should be run in transaction scope. So if you have method
#Transactional
public void doSomething(SomeClass arg) {...}
entering that method will create new transaction, and that transaction will be commited after leaving the transaction, if the transactional context doesn't exist. However, if that method is called from other method annotated with #Transactional, the parent transaction context will be used.
As alternative, you can use org.springframework.transaction.support.TransactionTemplate to gain more control over transactions (for example, launching separate transaction from transactional context).
Example:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// do something in trancation)
}
});
Note, that on some databases, such as Oracle, you can commit transaction within stored procedure, which will persist all changes made in existing transaction, and the new transaction will follow.

Spring transaction internals

The situation is as follows:
Method1 has four database update methods in it. The Method1 is annotated using the Spring transaction management semantics.
Method2 has a database read method in it and it is invoked after Method1 has finished executing all its database updates. Method2 is also annotated using the Spring transaction semantics.
There's a web request that comes in, the controller intercepts the request and invokes method1 and then method2.
A transaction is wrapped around the web-request as well.
What I am interested in knowing is:
1.How does Spring know to commit the database updates upon a successful transaction? Is there some reference to the Spring implementation that does the transaction management?
2.Since we have a hierarchy of transactions:
Transaction around the web-request->Transaction with Propagation=RequestNew for Method1->Transaction with Propagation=Required for Method2, how does Spring do the transaction management to ensure the transactions are executed within the proper context with the right order?
In short, it will be great to get a play by play account of how Spring performs the transaction management in all its grittiest details or a reference to documentation that doesn't simply hand-wave an explanation centered around JTA or some other acronym.
Thanks
Lets make some basic statements.
A transactional context is an environment where some special properties (database session) are made available to the application runtime which are otherwise not available. A Transaction Context is generally used to scope a transaction.
Spring uses, AOP Proxies and XML metadata to achieve a Declarative transaction management.
Annotations are used to mark the Transaction Propagation behavior of a particular method.
Spring uses Interceptor Mechanism to apply the transaction over the methods.
Here I am reusing the example give by #stacker above
MyClass{
#Transactional
public void sequence() {
method1();
method2();
}
#Transactional
void method1() {
}
#Transactional(propagation=Propagation.REQUIRES_NEW)
void method2() {
}
}
You can also achieve the same functionality using xml configuration as well. Lets take this as its popular and widely used.
At the time of deployment
Spring framework checks the xml configuration files (famed applicationContext.xml) and depending on the configuration, scans the code for #Transactional annotation (assuming that the configuration is mentioned as annotation based).
After this, it generates AOP proxies for methods marked for transaction. In simple terms, these proxies are nothing but wrapper around the concerned methods.
Within these wrapper methods, before and after a Transaction Advisor code is also generated depending on the configuration (namely the transaction propagation).
Now when these wrapper methods are invoked Transaction Advisor comes into picture before and after the actual method call. .
Representing the same in pseudo code for the example above
ProxyMyClass{
MyClass myclass;
.
.
.
sequence(){
//Transaction Advisor code (Typically begin/check for transaction)
myclass.sequence();
//Transaction Advisor code(Typically rollback/commit)
}
.
.
.
}
This is how spring managers the transaction. A slight oversimplification though.
Now to answer your questions,
.How does Spring know to commit the database updates upon a successful transaction? Is there some reference to the Spring implementation that does the transaction management?
Whenever you call a method under transaction, you actually call a proxy which first executes the transaction advisor (which will begin the transaction), then you call the actual business method, once that completes, another transaction advisor executes (which depending on way method returned, will commit or rollback transaction).
Since we have a hierarchy of transactions: Transaction around the web-request->Transaction with Propagation=RequestNew for Method1->Transaction with Propagation=Required for Method2, how does Spring do the transaction management to ensure the transactions are executed within the proper context with the right order?
In case of transaction hierarchy, the spring framework generates the Transaction Advisor checks accordingly. For the example you mentioned,
for method1 (RequestNew ) Transaction Advsor code (or transaction Advice) would be to create a new transaction always.
for method2 (Required ) Transaction Advisor code (or transaction Advice) would be check for existing transaction and use the same if it exists or else create a new transaction.
There is an image on the spring documentation page which very nicely summarizes these aspects.
Hope this helps.
Controller
#Transactional
public void sequence() {
method1();
method2();
}
#Transactional
void method1() {
}
#Transactional(propagation=Propagation.REQUIRES_NEW)
void method2() {
}
The default propagation is REQUIRED (Support a current transaction, create a new one if none exists.) Therefore m1 will use the Transaction started in the Controller. m2 is annotated as REQUIRES_NEW ( Create a new transaction, suspend the current transaction if one exists.) The order of the transaction is the order you call the transactional methods.
Controller
begin tx1
|--------------------> m1 (uses tx1)
|
| begin tx2
|--------------------> m2 (uses tx2)
| commit tx2
commit tx1
Have you read the Spring documentation? Basically AOP is used to manage the transaction. You should also read the AOP documentation. If the AOP documentation is not enough I suggest you go through the code. Stepping through the code in debug mode with break-point would be good.

#Transactional method calling another method without #Transactional anotation?

I've seen a method in a Service class that was marked as #Transactional, but it was also calling some other methods in that same class which were not marked as #Transactional.
Does it mean that the call to separate methods are causing the application to open separate connections to DB or suspend the parent transaction, etc?
What's the default behavior for a method without any annotations which is called by another method with #Transactional annotation?
When you call a method without #Transactional within a transaction block, the parent transaction will continue to the new method. It will use the same connection from the parent method (with #Transactional) and any exception caused in the called method (without #Transactional) will cause the transaction to rollback as configured in the transaction definition.
If you call a method with a #Transactional annotation from a method with #Transactional belonging to the same Spring Bean, then the called methods transactional behavior will not have any impact on the transaction. But if you call a method with a transaction definition from another method with a transaction definition, and they belong to different Spring Beans, then the code in the called method will follow its own transaction definitions.
You can find more details in the section Declarative transaction management of spring transaction documentation.
Spring declarative transaction model uses AOP proxy, so the AOP proxy is responsible for transactions creation. The AOP proxy will be active only if the called method belong to a different Spring Bean than the caller one.
Does that mean the call to separate methods are causing the application to open separate connections to DB or suspend the parent transaction, etc?
That depends on a propagation level. Here are all the possible level values.
For example in case a propagation level is NESTED a current transaction will "suspend" and a new transaction will be created ( note: actual creation of a nested transaction will only work on specific transaction managers )
What's the default behavior for a method without any annotations that is called by another method with #Transactional annotation?
The default propagation level ( what you call "behavior" ) is REQUIRED. In case an "inner" method is called that has a #Transactional annotation on it ( or transacted declaratively via XML ), it will execute within the same transaction, e.g. "nothing new" is created.
#Transactional marks the transaction boundary (begin/end) but the transaction itself is bound to the thread. Once a transaction starts it propagates across method calls until the original method returns and the transaction commits/rolls back.
If another method is called that has a #Transactional annotation then the propagation depends on the propagation attribute of that annotation.
The inner method will affect the outer method if the inner method is not annotated with #Transactional.
In case inner method is also annotated with #Transactional with REQUIRES_NEW, following will happen.
...
#Autowired
private TestDAO testDAO;
#Autowired
private SomeBean someBean;
#Override
#Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
testDAO.insertUser(user);
try{
someBean.innerMethod();
} catch(RuntimeException e){
// handle exception
}
}
#Override
#Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
throw new RuntimeException("Rollback this transaction!");
}
The inner method is annotated with REQUIRES_NEW and throws a RuntimeException so it will set its transaction to rollback but WILL NOT EFFECT the outer transaction. The outer transaction is PAUSED when the inner transaction starts and then RESUMES AFTER the inner transaction is concluded. They run independently of each other so the outer transaction MAY commit successfully.

Categories

Resources