springmvc事务的配置方式
springmvc配置事务方式有五种,好多都不怎么常用,说白了就是我也不会,最常用的基于注解的我还是有一些了解。我们来一起学习一下springmvc的事务配置方式。
首先来看声明式事务
- 1 使用tx标签
这种主要是要求开发者在方法起名的时候需要保持前缀一直。
- 2 使用代理的方式
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, readOnly
感觉和第一种很像,只是实现的方式不一样而已
- 3 使用拦截器
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, -Exception
PROPAGATION_REQUIRED, readOnly
transactionInterceptor
*Dao
这个就更少用了
- 4 使用全注解
这个就使用的很多了,我也就会使用这一种。因为这个使用很简单。直接看配置和代码
再看一下代码:
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//新增账单
orderService.insert(pk);
System.out.println("......");
}
- 5 编程式
意思就是自己在代码里实现事务,这个还是一个比较好的方式,可以精确的控制边界。
TransactionTemplate tt = new TransactionTemplate(); // 新建一个TransactionTemplate
Object result = tt.execute(
new TransactionCallback(){
public Object doTransaction(TransactionStatus status){
updateOperation();
return resultOfUpdateOperation();
}
}); // 执行execute方法进行事务管理
springmvc事务的传播行为
事务的传播行为有七种,接下来我们就一种一种探讨一下。
-
- propagation_required 默认的
具体来说就,如果当前没有事务就会新建一个事务,如果有事务就会加入当前事务。
- propagation_required 默认的
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//新增账单
//因为有事务所有,orderService.insert(pk)会加入当前事务
orderService.insert(pk);
}
总结起来就是这两个方法要么一起执行,要么一起回滚,不会一个执行成功,另外一个执行回滚。
- 2 propagation_requried_new
具体来说就是,methodA设置为requried,methodB设置为requried_new,当执行methodB的时候,会先挂起methodA,等待methodB执行完了,methodA才继续执行。
requried和requried_new 区别:
主要在于回滚程度了,methodB是新启的一个事务。
如果methodB执行失败,methodB肯定回滚,如果methodA捕获这个异常,methodA可以正常提交,如果methodA没有捕获methodA也回滚。
如果methodB执行成功,methodA执行失败,那么methodB不会回滚,methodA会执行回滚。
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//requried_new ,如果执行失败
try {
orderService.insert(pk);
}catch (Exception e){
//不做处理,让当前事务执行完
}
System.out.println("......");
}
//requried_new
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void insert(int userId) {
Order order = new Order();
order.setDescs("desc yx");
order.setOrderId("0101");
order.setUserId(userId);
orderDao.insert(order);
int i = 1/0;
}
执行结果:
user表有数据,order表没有数据。
我们在换成另外一种情况, orderService.insert(pk);执行成功
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//requried_new ,如果执行失败
// try {
orderService.insert(pk);
// }catch (Exception e){
// //不做处理,让当前事务执行完
// }
int i = 1/0;
System.out.println("......");
}
//requried_new
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void insert(int userId) {
Order order = new Order();
order.setDescs("desc yx");
order.setOrderId("0101");
order.setUserId(userId);
orderDao.insert(order);
// int i = 1/0;
}
执行结果:
order表有数据,user没有数据。
- 3 propagation_nested
具体来说,就是嵌套事务。
第一种情况:
nested事务抛了异常,外部事务捕获了异常。
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//NESTED ,如果执行失败
try {
orderService.insert(pk);
}catch (Exception e){
System.out.println("可以继续执行这里面的逻辑.....");
}
System.out.println("当前事务继续执行......");
}
//NESTED
@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
public void insert(int userId) {
Order order = new Order();
order.setDescs("desc yx");
order.setOrderId("0101");
order.setUserId(userId);
orderDao.insert(order);
int i = 1/0;
}
结果是:
外部事务正常执行,嵌套事务回滚。
第二种情况:嵌套事务正常执行完成,外部事务抛了异常。
//首先设置为requried
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
public void insert() {
User user = new User();
user.setName("yuxi");
int pk = userDao.insert(user);
//NESTED ,如果执行失败
try {
orderService.insert(pk);
}catch (Exception e){
System.out.println("可以继续执行这里面的逻辑.....");
}
int i = 1/0;
System.out.println("当前事务继续执行......");
}
//NESTED
@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
public void insert(int userId) {
Order order = new Order();
order.setDescs("desc yx");
order.setOrderId("0101");
order.setUserId(userId);
orderDao.insert(order);
// int i = 1/0;
}
结果是:
两个都被回滚了,我理解这个就是嵌套事务和requried_new 的最大区别了。
4 propagation_supported
具体来说,就是支持当前事务,如果没有就以非事务的方式运行。5 propagation_not_supported
具体来说就是不支持以事务的方式运行,如果当前有事物就会挂起。6 propagation_never
具体来说,就是不支持事务的方式运行,如果有事务就会抛出异常。7 propagation_mandatory
具体来说,就是支持当前事务,如果当前没有事务,就抛出异常。
后面的基本都不常用。
参考文章:
http://blog.csdn.net/it_wangxiangpan/article/details/24180085
http://blog.csdn.net/paincupid/article/details/48185597