Spring Transaction propagation / readonly

1. abstraction

I would expose a simple post with 2 examples concerning the propagation of a transaction in the application layers (Spring MVC controller, Manager layer, Service Layer, DAO layer) with the use of Propagation.REQUIRED and the readOnly attribute in the @Transactionnal annotation like:
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)

2. test

step1 :
In this 1st test, we will study a simple example with a no-transactional Spring MVC controller
MyController:
public class MyController extends MultiActionController {
	public ModelAndView handleMyAction(HttpServletRequest request, HttpServletResponse 
                      response) throws ServletException, IOException, InterruptedException {
		//...
		myManager.myMethod(param1);
		//...
	}
}
which calls a manager class MyManagerImpl in the sub-layer:
@Transactional(readOnly = true)
@Service("myManager")
public class MyManagerImpl implements MyManager {

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void myMethod(String param1){
		myService.myMethod(param1);
	}
}
which calls a service class MyServiceImpl in the sub-layer:
@Transactional(readOnly = true) 
@Service("myService")
public class MyServiceImpl implements MyService {

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void myMethod(String param1){
		//...
		myDao.createOrUpdate(myObject);
		//...
	}
}
which calls a DAO class MyDaoHibernateImpl in the sub-layer:
@Transactional(propagation=Propagation.MANDATORY)
public class MyDaoHibernateImpl extends GenericDaoImpl<MyObject, String> implements MyDao {
	public void createOrUpdate(T o) {	
		//...
		if (o instanceof AbstractPersistentObject) {
			if (((AbstractPersistentObject) o).isCreation()) {
				getSession().saveOrUpdate(o);
			} else {
				getSession().merge(o);
			}
		} else {
		throw new RuntimeException("this method support only AbstractPersistentObject");
		}
		//...
	}

}
So, the result is that the data (in database) are modified/updated because:
  • the Spring MVC controller MyController is no-transactional component,
  • the method MyManagerImpl.myMethod(String param1) is NOT READONLY and supports the current transaction, or will create a new one if none exists (REQUIRED),
  • the method MyServiceImpl.myMethod(String param1) is also NOT READONLY and supports the current transaction, or will create a new one if none exists (REQUIRED),
  • and the latest MyDaoHibernateImpl supports the current transaction and throws an exception if none exists transaction (MANDATORY).
step2 :In this 2nd test, we will study a more complex example with a no-transactional Spring MVC controller MyController:
public class MyController extends MultiActionController {
	public ModelAndView handleMyAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, InterruptedException {
		//...
		myManager.myMethod(param1);
		//...
	}

}
which calls a manager class MyManagerImpl in the sub-layer. In this example, we will modify the attribute readOnly = false to the value readOnly = true:
@Transactional(readOnly = true)
@Service("myManager")
public class MyManagerImpl implements MyManager {

	@Override
	@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
	public void myMethod(String param1){
		myService.myMethod(param1);
	}
...
}
which calls a service class MyServiceImpl in the sub-layer:
@Transactional(readOnly = true) 
@Service("myService")
public class MyServiceImpl implements MyService {

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void myMethod(String param1){
		//...
		myDao.createOrUpdate(myObject);
		//...
	}
}
which calls a DAO class MyDaoHibernateImpl in the sub-layer:
@Transactional(propagation=Propagation.MANDATORY)
public class MyDaoHibernateImpl extends GenericDaoImpl<MyObject, String> implements MyDao {
	public void createOrUpdate(T o) {	
		//...
		if (o instanceof AbstractPersistentObject) {
			if (((AbstractPersistentObject) o).isCreation()) {
				getSession().saveOrUpdate(o);
			} else {
				getSession().merge(o);
			}
		} else {
			throw new RuntimeException("this method support only 
                             AbstractPersistentObject");
		}
		//...
	}

}
So, we have:
  • the Spring MVC controller MyController is no-transactional component,
  • the method MyManagerImpl.myMethod(String param1) is READONLY and supports the current transaction, or will create a new one if none exists (REQUIRED),
  • the method MyServiceImpl.myMethod(String param1) is also NOT READONLY and supports the current transaction, or will create a new one if none exists (REQUIRED),
  • and the latest MyDaoHibernateImpl supports the current transaction and throws an exception if none exists transaction (MANDATORY).
the result is that the data (in database) are NOT modified/updated because the method MyServiceImpl.myMethod(String param1) supports the current transaction which has been created READNLY in the method MyManagerImpl.myMethod(String param1).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值