Spring事务管理,声明式事务和编程式事务实现

数据库操作过程中,对于增删改等操作,因为涉及到数据库状态的变更,为保证数据安全,需要进行事务管理;Spring事务管理有两种方式,即声明式事务管理和编程式事务管理;

连接池配置:

jdbc configuration
jdbc.url=jdbc\:mysql\://127.0.0.1\:3306/ssm?useUnicode\=true&characterEncoding\=utf8&characterSetResults\=utf8
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456

以下为 优化配置
jdbc.filters=stat

jdbc.maxActive=20
jdbc.initialSize=1
jdbc.maxWait=60000
jdbc.minIdle=10
jdbc.maxIdle=15

jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000

jdbc.validationQuery=SELECT 'x'
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false

jdbc.maxOpenPreparedStatements=20
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=1800
jdbc.logAbandoned=true


代码演示:

package com.dongzz.ssm.modules.system.service;

import com.dongzz.ssm.SpringBaseJunit;
import com.dongzz.ssm.modules.system.entity.SysUser;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.sql.DataSource;

/**
 * 编程式事务管理
 */
public class UserServiceTest extends SpringBaseJunit {

    @Autowired
    PlatformTransactionManager transactionManager;
    @Autowired
    DataSource dataSource;

    JdbcTemplate jdbcTemplate;

    @Test
    public void transactionTest() {
        String sql1 = "update book set name = '算法导论(原书篇3版)' where id = 1";
        String sql2 = "update book set name = 'Java编程思想(篇4版)' where id = 2";
        // 设置事务隔离级别 传播特性
        DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
        dtd.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 获取事务状态,spring根据传播行为来开启事务
        TransactionStatus status = transactionManager.getTransaction(dtd);
        jdbcTemplate = new JdbcTemplate(dataSource);
        try {
            jdbcTemplate.update(sql1);
            jdbcTemplate.update(sql2);
            transactionManager.commit(status); // 提交事务
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback(status); // 回滚事务
        }
    }
}

借助 spring 的 TransactionTemplate 工具类简化事务管理编码;

@Test
public void transactionTemplateTest() {
    String sql1 = "update book set name = '算法导论(原书篇3版)' where id = 1";
    String sql2 = "update book set name = 'Java编程思想(篇4版)' where id = 2";

    jdbcTemplate = new JdbcTemplate(dataSource);
    TransactionTemplate template = new TransactionTemplate(transactionManager);
    template.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    template.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
            jdbcTemplate.update(sql1);
            jdbcTemplate.update(sql2);
        }
    });
}

spring xml 添加如下配置:


使用演示:

在需要开启事务管理的类或方法上添加 @Transactional 注解即可;

package com.dongzz.ssm.modules.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import com.dongzz.ssm.common.base.impl.BaseMybatisServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dongzz.ssm.common.plugin.datatables.PageTableHandler;
import com.dongzz.ssm.common.plugin.datatables.PageTableHandler.CountHandler;
import com.dongzz.ssm.common.plugin.datatables.PageTableHandler.ListHandler;
import com.dongzz.ssm.common.plugin.datatables.PageTableHandler.OrderHandler;
import com.dongzz.ssm.common.exception.ServiceException;
import com.dongzz.ssm.common.plugin.datatables.PageTableRequest;
import com.dongzz.ssm.common.plugin.datatables.PageTableResponse;
import com.dongzz.ssm.modules.system.dao.SysUserMapper;
import com.dongzz.ssm.modules.system.entity.SysUser;
import com.dongzz.ssm.modules.system.service.UserService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl extends BaseMybatisServiceImpl implements UserService {

    @Autowired
    private SysUserMapper userMapper;

    @Override
    @Transactional
    public void addUser(SysUser user) throws Exception {
        SysUser u = userMapper.selectUserByUname(user.getUsername());
        if (null != u) {
            throw new ServiceException("用户名已存在");
        }
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setStatus("1");
        user.setIsDel("0");
        userMapper.insertSelective(user);
    }
}

spring xml 添加如下配置:


上述配置将 txAdvice 切面中的通知方法动态的切入到名称为 pc 的切入点表达式对应的位置,所有通配符匹配的方法均纳入事务管理;

Original: https://www.cnblogs.com/herokevin/p/15837679.html
Author: 暴走编程
Title: Spring事务管理,声明式事务和编程式事务实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/573204/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • leetcode 208. Implement Trie (Prefix Tree) 实现 Trie (前缀树) (中等)

    Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼…

    Java 2023年6月14日
    068
  • Java 设计模式 – Observer 观察者模式

    说明都在注释: package ObserverModel; package ObserverModel; <span class="hljs-keyword&qu…

    Java 2023年6月9日
    048
  • Sharepoint 2013 安装部署系列篇 第一篇 — 系统集群安装

    这部分讲述怎样配置两台服务器作为sql集群. 准备 你需要两个网卡在每台服务器上,一个是共有,另一个是私有的(heartbreak通信) 共享存储如SAN存储需要至少如下配置,并且…

    Java 2023年6月7日
    072
  • spring 工具类大集合

    org.springframework.util.AntPathMatcher 它可以帮助我们做一些路径的匹配,可以用于路径映射规则匹配 。? (任何单字符) * (任意数量字符)…

    Java 2023年6月5日
    0103
  • == 和 equals 的区别是什么?

    ==:基本类型比较的是值的大小,引用类型比较的是内存地址,是不是同一个对象,equals:默认比较同一个对象的内容 == 和 equals 的区别是什么? == : 它的作用是判断…

    Java 2023年6月13日
    062
  • 反射 父类

    现有每多个javabean,但是每个bean中都有不同的属性,并且都是通过get和set方法来修改和获取值。如果调试一步一步去猜内部结构,想用一个方法可以获取不同对像中各个属性的值…

    Java 2023年5月30日
    041
  • 线程池,我是谁?我在哪儿?

    大家好,这篇文章跟大家探讨下日常使用线程池的各种姿势,重点介绍怎么在 Spring 环境中正确使用线程池。 线程池使用姿势 首先问大家一个问题,你日常开发中是怎样使用线程池的? 我…

    Java 2023年6月14日
    081
  • Java中的final关键字

    字面意思:被final修饰的对象是无法改变的。 一、final数据: (2)同时被static和final修饰的数据占据一段不能被改变的存储空间,同时,由于static的作用,该数…

    Java 2023年5月29日
    085
  • 杨辉三角Java杭电oj2032

    2032 杨辉三角 杨辉三角,是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623—-1662)…

    Java 2023年6月6日
    070
  • 图解:HTTP 范围请求,助力断点续传、多线程下载的核心原理

    题图:by Charles Loyer 一、序 Hi,大家好,我是承香墨影! HTTP 协议在网络知识中占据了重要的地位,HTTP 协议最基础的就是请求和响应的报文,而报文又是由报…

    Java 2023年5月30日
    057
  • Java 多线程

    线程创建, Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程,如下所示: 1)继承Thread类创建线程 2…

    Java 2023年6月9日
    075
  • Effective Java 第三版——82. 线程安全文档化

    Tips书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code注意,书中的有些代码里方法是基于Java 9…

    Java 2023年5月29日
    091
  • 反射取得静态类中的属性,方法,字段

    欢迎加我的QQ群:193522571,一起来讨论、交流! Type BstrType = typeof(CadBaseSet);DataTable dt = (DataTable)…

    Java 2023年5月30日
    073
  • 设计模式-day01

    1,设计模式概述 1.1 软件设计模式的产生背景 “设计模式”最初并不是出现在软件设计中,而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼…

    Java 2023年6月13日
    047
  • 动力节点-王妈妈Springboot教程(三)Spring Boot和web组件

    第三章 Spring Boot 和 web 组件 *笔记中的视频观看地址 https://www.bilibili.com/video/BV1XQ4y1m7ex 3.1 Sprin…

    Java 2023年6月7日
    0106
  • Java Servlet(十二):Servlet、Listener、Filter之间的执行流程分析

    时隔几年后,看到本系列文章讲解的内容缺少了不少内容:周末无事分析了Spring Security是如何被集成到Web Servlet(SpringMVC)时,需要重新理清Filte…

    Java 2023年5月29日
    085
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球