SpringMVC+MyBatis 事务管理(实例)

网友投稿 324 2023-04-24


SpringMVC+MyBatis 事务管理(实例)

前言

spring事务管理包含两种情况,编程式事务、声明式事务。而声明式事务又包括基于注解@Transactional和tx+aop的方式。那么本文先分析编程式注解事务和基于注解的声明式事务。 编程式事务管理使用TransactionTemplate或者PlatformTransactionManager。对于编程式事务spring推荐使用TransactionTemplate。

一、编程式事务

sprYCnKlGing事务特性

spring中所有的事务策略类都继承自org.springframework.transaction.PlatformTransactionManager接口

public interface PlatformTransactionManager {

TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

void commit(TransactionStatus status) throws TransactionException;

void rollback(TransactionStatus status) throws TransactionException;

}

编程式事务TransactionTemplate需要手动在代码中处理事务,一般不推荐使用,也不符合spring的思想,因为它直接耦合代码,但各有利弊。先看下TransactionTemplate的源码。

public class TransactionTemplate extends DefaultTransactionDefinition

implements TransactionOperations, InitializingBean {

protected final Log logger = LogFactory.getLog(getClass());

private PlatformTransactionManager transactionManager;

public TransactionTemplate() {

}

public TransactionTemplate(PlatformTransactionManager transactionManager) {

this.transactionManager = transactionManager;

}

public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {

super(transactionDefinition);

this.transactionManager = transactionManager;

}

public void setTransactionManager(PlatformTransactionManager transactionManager) {

this.transactionManager = transactionManager;

}

public PlatformTransactionManager getTransactionManager() {

return this.transactionManager;

}

@Override

public void afterPropertiesSet() {

if (this.transactionManager == null) {

throw new IllegalArgumentException("Property 'transactionManager' is required");

}

}

@Override

public T execute(TransactionCallback action) throws TransactionException {

if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {

return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);

}

else {

TransactionStatus status = this.transactionManager.getTransaction(this);

T result;

try {

result = action.doInTransaction(status);

}

catch (RuntimeException ex) {

// Transactional code threw application exception -> rollback

rollbackOnException(status, ex);

throw ex;

}

catch (Error err) {

// Transactional code threw error -> rollback

rollbackOnException(status, err);

throw err;

}

catch (Throwable ex) {

// Transactional code threw unexpected exception -> rollback

rollbackOnException(status, ex);

throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");

}

this.transactionManager.commit(status);

return result;

}

}

private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {

logger.debug("Initiating transaction rollback on application exception", ex);

try {

this.transactionManager.rollback(status);

}

catch (TransactionSystemException ex2) {

logger.error("Application exception overridden by rollback exception", ex);

ex2.initApplicationException(ex);

throw ex2;

}

catch (RuntimeException ex2) {

logger.error("Application exception overridden by rollback exception", ex);

throw ex2;

}

catch (Error err) {

logger.error("Application exception overridden by rollback error", ex);

throw err;

}

}

}

从上面的代码可以看到核心方法是execute,该方法入参TransactionCallback。查看TransactionCallback源码:

public interface TransactionCallback {

T doInTransaction(TransactionStatus status);

}

那么以上两个源码可以确定我们使用编程式事务管理的方式也就是自己需要重写doInTransaction()。OK,那么我们手动使用TransactionTemplate处理下。

1、先配置transactionmanager

2、配置transactionTemplate

class="org.springframework.transaction.support.TransactionTemplate">

class="org.springframework.transaction.support.TransactionTemplate">

3、业务代码处理

@Autowired

private TransactionTemplate transactionTemplate;

public int insertUser2(final User user) {

Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallbackhttp://() {

public Object doInTransaction(TransactionStatus transactionStatus) {

int i = userMapper.insertUser(user);

if (i > 0) {

System.out.println("success");

}

int j = 10 / 0;

return i;

}

});

return i;

}

业务代码中我们使用by zero的异常故意抛出,你会发现能继续打印success,当你断点debug时,你会发现数据库一直是锁定状态,直到你程序执行完。如下图:

二、基于Transactional注解的事务管理

当前应该是使用最清爽的事务管理方式了,也符合spring的理念,非入侵代码的方式。

1、配置

2、配置后只需要在要处理的地方加上Transactional注解,而且Transactional注解的方式可以应用在类上,也可以应用在方法上,当然只针对public方法。

3、业务代码处理

@Transactional

public int insertUser(User user) {

int i = userMapper.insertUser(user);

if (i > 0) {

System.out.println("success");

}

int j = 10 / 0;

return i;

}

总结

以上所述是给大家介绍的SpringMVC+MyBatis 事务管理,希望对大家有所帮助,如果大家有任何疑问请给我留言,会及时回复大家的。在此也非常感谢大家对我们网站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:开源api网关选型(api网关的优缺点)
下一篇:浅析Java8新特性Lambda表达式和函数式接口
相关文章

 发表评论

暂时没有评论,来抢沙发吧~