SpringMVC+MyBatis 事务管理(实例)

作者:garfieldzf 时间:2022-07-30 11:04:40 

前言

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

一、编程式事务

     spring事务特性

     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> T execute(TransactionCallback<T> 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<T>。查看TransactionCallback源码:


public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus status);
}

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

1、先配置transactionmanager


<!--事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>

2、配置transactionTemplate


<!--编程式事务,推荐使用TransactionTemplate-->
<bean id="transactionTemplate"
  class="org.springframework.transaction.support.TransactionTemplate">
 <property name="transactionManager" ref="transactionManager"/>
</bean>

3、业务代码处理


@Autowired
private TransactionTemplate transactionTemplate;
public int insertUser2(final User user) {
 Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallback() {
  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时,你会发现数据库一直是锁定状态,直到你程序执行完。如下图:

SpringMVC+MyBatis 事务管理(实例)

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

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

1、配置


<!--事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用注解事务,需要添加Transactional注解属性 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--启用最新的注解器、映射器-->
<mvc:annotation-driven/>

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 事务管理网站的支持!

来源:http://www.cnblogs.com/sword-successful/p/7274929.html

标签:springmvc,mybatis,事务管理
0
投稿

猜你喜欢

  • 浅析Java中的内存泄漏

    2023-12-19 02:29:02
  • C#中使用IFormattable实现自定义格式化字符串输出示例

    2023-05-31 23:34:04
  • Android实现银行卡号扫描识别功能

    2021-09-05 01:56:50
  • 利用栈使用简易计算器(Java实现)

    2023-07-22 02:02:11
  • c#使用ManagedWifi查看当前Wifi信号并选择wifi的示例

    2021-07-06 15:37:18
  • java多线程CyclicBarrier的使用案例,让线程起步走

    2023-05-20 16:22:22
  • SpringBoot @PropertySource与@ImportResource有什么区别

    2023-08-22 02:02:47
  • Java中String的JdbcTemplate连接SQLServer数据库的方法

    2022-09-05 00:34:12
  • 深入了解Java设计模式之策略模式

    2021-06-24 22:45:56
  • Ubuntu搭建Java开发环境笔记

    2023-10-10 14:27:49
  • Java Web 简单的分页显示实例代码

    2023-04-19 20:06:21
  • Java面向对象基础,类,变量,方法

    2023-04-08 13:21:49
  • postman测试传入List<String>参数方式

    2022-10-13 01:34:40
  • c#使用filesystemwatcher监视文件系统的变化

    2022-08-06 15:28:43
  • SpringBoot整合Elasticsearch并实现CRUD操作

    2021-10-28 07:27:31
  • spring cloud gateway中如何读取请求参数

    2021-08-19 16:19:02
  • Android中如何获取视频文件的截图、缩略图

    2022-06-29 04:24:03
  • springboot+rabbitmq实现智能家居实例详解

    2022-09-05 12:23:39
  • 简单讲解Android开发中触摸和点击事件的相关编程方法

    2023-03-30 12:29:10
  • C#基于TimeSpan实现倒计时效果的方法

    2021-10-19 00:06:04
  • asp之家 软件编程 m.aspxhome.com