Spring集成事务代码实例

 更新时间:2023年10月18日 09:09:03   作者:喜上编程  
这篇文章主要介绍了Spring集成事务代码实例,pring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交,需要的朋友可以参考下

Spring事务

Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交。

有了Spring,我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作,使得我们把更多的精力放在处理业务上。

事实上Spring并不直接管理事务,而是提供了多种事务管理器。他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

一、编程式事务

编程式事务管理我们可以通过PlatformTransactionManager实现来进行事务管理,同样的Spring也为我们提供了模板类TransactionTemplate进行事务管理,下面主要介绍模板类,我们需要在配置文件中配置。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--    开启注解-->
    <context:component-scan base-package="com.it.spring.tx"></context:component-scan>
<!--    引入工程中src下的db.properties文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--    设置连接数据库的值  spring管理c3p0数据库连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${url}"></property>
        <property name="user" value="${user}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="password" value="${password}"></property>
    </bean>
<!--    配置平台事物管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--配置平台事物管理模板    事务管理的模板类-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
    </bean>
</beans>

编写DAO接口

package com.it.spring.tx.dao;
/**
 * 实现转账业务
 */
public interface
AccountDAO {

    //出账
    void outMoney(String from,Double money);
    //入账
    void inMoney(String in,Double money);   
}

DAO实现类

package com.it.spring.tx.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;
@Repository
//JdbcDaoSupport就是为了简化我们dao类有关JdbcTemplate的注入的相关工作量。
public class AccountDAOImpl extends JdbcDaoSupport implements AccountDAO {
    @Resource
    private DataSource dataSource;
    //初始化dataSources
    @PostConstruct
    private  void init(){
        //调用JdbcDaoSupport的setDataSource方法  或者使用带参构造函数
        setDataSource(dataSource);
    }
    @Override
    public void outMoney(String from, Double money) {
        System.out.println(getJdbcTemplate());
            getJdbcTemplate().update("update account set money=money-? where id=?",money,from);
    }
    @Override
    public void inMoney(String in, Double money) {
            getJdbcTemplate().update("update account set money=money+? where id=?",money,in);
    }
}

service接口

package com.it.spring.tx.service;
/**
 * 实现转账业务
 */
public interface AccountService {
    void transfer(String from,String to,Double money);
}

service实现类

package com.it.spring.tx.service;
import com.it.spring.tx.dao.AccountDAO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
@Service
public class AccountServiceImpl implements AccountService {
    @Resource
    AccountDAO accountDAO;
    //而TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装
    @Resource
   private TransactionTemplate transactionTemplate;
//    @Override
//    public void transfer(String from, String to, Double money) {
//        accountDAO.outMoney(from,money);
        System.out.println(12/0);
//        //添加事务进行解决   使用TransactionTemplate模块
//        accountDAO.inMoney(to,money);
//    }


@Override
public void transfer(String from, String to, Double money) {
    //所以当我们借助TransactionTemplate.execute( ... )执行事务管理的时候,传入的参数有两种选择:
    //1、TransactionCallback
    //2、TransactionCallbackWithoutResult
    //两种区别从命名看就相当明显了,一个是有返回值,一个是无返回值。这个的选择就取决于你是读

//    //设置事务传播属性
//    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//    // 设置事务的隔离级别,设置为读已提交(默认是ISOLATION_DEFAULT:使用的是底层数据库的默认的隔离级别)
//    transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
//    // 设置是否只读,默认是false
//    transactionTemplate.setReadOnly(true);
//    // 默认使用的是数据库底层的默认的事务的超时时间
//    transactionTemplate.setTimeout(30000);
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    try {
                        accountDAO.outMoney(from, money);
                        System.out.println(12 / 0);
                        accountDAO.inMoney(to, money);
                    } catch (Exception e){
                        //回滚状态
                        transactionStatus.setRollbackOnly();
                    }
                }
            });
    }
}

测试类

package com.it.spring.tx.test;

import com.it.spring.tx.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:applicationContext.xml")
public class SpringTxTest1 {
     @Resource
     AccountService accountService;
     @Test
     public void Test1(){
         accountService.transfer("18","17",1000.0);
     }
}

二、声明式事务

声明式事务管理有两种常用的方式,一种是基于tx和aop命名空间的xml配置文件,一种是基于@Transactional注解,随着Spring和Java的版本越来越高,大家越趋向于使用注解的方式,下面我们两个都说。

1.基于tx和aop命名空间的xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <context:component-scan base-package="com.it.spring.tx2.*"></context:component-scan>
    
    <!-- 引入工程中src下的db.properties文件2-->

 <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
     <!-- spring管理c3p0数据库连接池-->

  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="driverClass" value="${driverClass}"></property>
      <property name="jdbcUrl" value="${url}"></property>
      <property name="password" value="${password}"></property>
      <property name="user" value="${user}"></property>
  </bean>
    <!--配置平台事物管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--    配置增强(就是自定义的的切面) -->

<!--     配置事物增强-->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--         propagation事务传播行为    isolation隔离机制-->
        <tx:attributes>
<!--            <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"></tx:method>-->
<!--            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"></tx:method>-->
<!--            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"></tx:method>-->
<!--            <tx:method name="query*" read-only="true"></tx:method>-->
            <tx:method name="*" propagation="REQUIRED"></tx:method>
        </tx:attributes>
    </tx:advice>

<!--          配置AOP-->
    <aop:config>
<!--        设置切点-->
        <aop:pointcut id="pointcut1" expression="execution(* com.com.it.spring.tx2.service.AccountServiceImpl.transfer(..))"></aop:pointcut>
<!--        aop:aspect 多个通知和多个切入点的组合-->
        <!--aop:advisor 单个通知和单个切入点的组合-->
        <aop:advisor pointcut-ref="pointcut1" advice-ref="txAdvice"></aop:advisor>
    </aop:config>
</beans>

service实现类发生变化

package com.it.spring.tx2.service;
import com.it.spring.tx2.dao.AccountDAO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
 @Service("accountService")
public class AccountServiceImpl implements AccountService {
     @Resource
     AccountDAO accountDAO;
    @Override
    public void transfer(String from, String to, Double money) {
        accountDAO.outMoney(from,money);
//        System.out.println(12/0);
        accountDAO.inMoney(to,money);
    }
}

测试类

package com.it.spring.tx2.test;
import com.it.spring.tx2.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:applicationContext2.xml")
public class SpringTxTest2 {
  @Resource
  AccountService accountService;
  @Test
  public void fun1(){
    accountService.transfer("11","10",1000.0);
  }
}

2.基于@Transactional注解

这种方式最简单,也是最为常用的,只需要在配置文件中开启对注解事务管理的支持。

applicationContext3.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">   
   <context:component-scan base-package="com.it.spring.tx3.*"></context:component-scan>   
    <!-- 引入工程中src下的db.properties文件2-->
 <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
     <!-- spring管理c3p0数据库连接池-->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="driverClass" value="${driverClass}"></property>
      <property name="jdbcUrl" value="${url}"></property>
      <property name="password" value="${password}"></property>
      <property name="user" value="${user}"></property>
  </bean>
    <!--配置平台事物管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
  <!-- 开启事物注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

services实现类

package com.it.spring.tx3.service;

import com.it.spring.tx3.dao.AccountDAO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
//在业务层添加注解
 @Service
 @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService {
     @Resource
     AccountDAO accountDAO;
    @Override
    public void transfer(String from, String to, Double money) {
        accountDAO.outMoney(from,money);
//       System.out.println(12/0);
        accountDAO.inMoney(to,money);
    }
}

以上就是Spring管理事务的方式。感谢阅读。

到此这篇关于Spring集成事务代码实例的文章就介绍到这了,更多相关Spring事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java常用类之System类的使用指南

    Java常用类之System类的使用指南

    System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。本文将通过示例为大家详细讲讲System类的使用,需要的可以参考一下
    2022-07-07
  • java实现单词查询小程序

    java实现单词查询小程序

    这篇文章主要为大家详细介绍了java实现单词查询小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • springboot整合druid连接池的步骤

    springboot整合druid连接池的步骤

    这篇文章主要介绍了springboot整合druid连接池的步骤,帮助大家更好的理解和学习springboot框架,感兴趣的朋友可以了解下
    2020-11-11
  • java的json解析类库使用示例

    java的json解析类库使用示例

    这篇文章主要介绍了java的json解析类库使用方法,这里使用Zson解析json,这是一个开源的json处理类库
    2014-03-03
  • spring boot executable jar/war 原理解析

    spring boot executable jar/war 原理解析

    spring boot里其实不仅可以直接以 java -jar demo.jar的方式启动,还可以把jar/war变为一个可以执行的脚本来启动,比如./demo.jar,这篇文章主要介绍了spring boot executable jar/war 原理,需要的朋友可以参考下
    2023-02-02
  • Java swing框架实现的贪吃蛇游戏完整示例

    Java swing框架实现的贪吃蛇游戏完整示例

    这篇文章主要介绍了Java swing框架实现的贪吃蛇游戏,结合完整实例形式分析了java使用swing框架结合awt图形绘制实现贪吃蛇游戏的具体步骤与相关实现技巧,需要的朋友可以参考下
    2017-12-12
  • Spring Boot集成教程之异步调用Async

    Spring Boot集成教程之异步调用Async

    在项目中,当访问其他人的接口较慢或者做耗时任务时,不想程序一直卡在耗时任务上,想程序能够并行执行,我们可以使用多线程来并行的处理任务,也可以使用spring提供的异步处理方式@Async。需要的朋友们下面来一起看看吧。
    2018-03-03
  • Spring搭配Ehcache实例解析

    Spring搭配Ehcache实例解析

    这篇文章主要为大家详细介绍了Spring搭配Ehcache实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • SpringBoot 中使用 Validation 校验参数的方法详解

    SpringBoot 中使用 Validation 校验参数的方法详解

    Validation 是用于检查程序代码中参数的有效性的框架,作为 Spring 框架中的一个参数校验工具,集成在 spring-context 包中,这篇文章主要介绍了SpringBoot 中使用 Validation 校验参数,需要的朋友可以参考下
    2022-05-05
  • 一文详解Java中的类加载机制

    一文详解Java中的类加载机制

    Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。本文将详解Java的类加载机制,需要的可以参考一下
    2022-05-05

最新评论