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)

大家都在看

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