当前位置: 首页 > news >正文

Spring2:应用事务+连接池形成的工具类

工具类

package com.qcby.utils;import com.alibaba.druid.pool.DruidDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;/*** 事务的工具类*/
//事务是通过连接开启的,所以要保证是同一个连接
public class TxUtils {//连接池对象private static DruidDataSource ds = null;//使用ThreadLocal存储当前线程中的connection对象private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();//在静态代码块中创建数据库连接池static {try {//通过代码创建C3P0数据库连接池ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql:///spring_db");ds.setUsername("root");ds.setPassword("root");}catch (Exception e) {throw new ExceptionInInitializerError(e);}}/*** @Method: getConnection* @Description: 丛数据源中获取数据库连接* @Anthor:* @return Connection* @throws SQLException* 保证是相同的连接*/public static Connection getConn() throws SQLException{//从当前线程中获取ConnectionConnection conn = threadLocal.get();if(conn == null){//从数据源中获取数据库连接conn = getDataSource().getConnection();//将conn绑定到当前线程threadLocal.set(conn);}return conn;}/*** @Method: startTransaction* @Description: 开启事务* @Anthor:**/public static void startTransaction(){try {Connection conn = threadLocal.get();if(conn == null) {conn = getConn();//把conn绑定到当前线程上threadLocal.set(conn);}//开启事务conn.setAutoCommit(false);} catch (SQLException e) {throw new RuntimeException(e);}}/*** @Method: rollback* @Description:回滚事务* @Anthor:*/public static void rollback(){try {//从当前线程中获取connectionConnection conn = threadLocal.get();if(conn != null){//回滚事务conn.rollback();}}catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: commit* @Description:提交事务* @Anthor:*/public static void commit(){try {//从当前线程中获取connectionConnection conn = threadLocal.get();if(conn != null){//提交事务conn.commit();}}catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: close* @Description:关闭数据库连接(注意,并不是真的关闭,而是把连接还给数据库连接池)* @Anthor:**/public static void close(){try {Connection conn = threadLocal.get();if(conn != null){conn.close();//解除当前线程上绑定conn,使得每次使用的数据库是一个threadLocal.remove();}} catch (SQLException e) {throw new RuntimeException(e);}}/*** @Method: getDataSource* @Description: 获取数据源* @Anthor:* @return DataSource*/public static DataSource getDataSource(){//从数据源中获取数据库连接return ds;}
}

持久层

package com.qcby.dao;import com.qcby.model.Account;
import com.qcby.utils.TxUtils;
import org.springframework.stereotype.Repository;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;@Repository
public class AccountDaoImpl implements AccountDao {public void save(Account account) {try {//创建连接Connection conn = TxUtils.getConn();//编写sql语句String sql = "update account set money = money - 10 where name = ? ";//预编译sql语句PreparedStatement statement = conn.prepareStatement(sql);//设置值statement.setString(1,account.getName());//执行操作statement.executeUpdate();//关闭资源statement.close();} catch (SQLException e) {e.printStackTrace();}}
}

业务层(service)

package com.qcby.service.impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;
import com.qcby.utils.TxUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;public void saveAll(Account account1, Account account2) {try {//开启事务TxUtils.startTransaction();accountDao.save(account1);//int res = 10/0;accountDao.save(account2);TxUtils.commit();}catch (Exception e){e.printStackTrace();//事务回滚TxUtils.rollback();}finally {//关闭资源TxUtils.close();}}
}
http://www.xdnf.cn/news/491401.html

相关文章:

  • FC7300 Trigger MCAL配置引导
  • Android应用内存分析与优化 - 工具篇之Booster
  • ThinkStation图形工作站进入BIOS方法
  • 读论文alexnet:ImageNet Classification with Deep Convolutional Neural Networks
  • C++循环效率比较与优化建议
  • 现代计算机图形学Games101入门笔记(十三)
  • 二叉树子树判断:从递归到迭代的全方位解析
  • uniapp-商城-60-后台 新增商品(属性的选中和页面显示,数组join 的使用)
  • rocketmq并发消费
  • 从零开始掌握FreeRTOS(4)任务的动态和静态创建
  • 实验-实现向量点积-RISC-V(计算机组成原理)
  • 使用 ESP32 驱动 ±12V 压电无源蜂鸣器(NPN 三极管 + PWM 控制驱动电路)
  • Typescript学习教程,从入门到精通,TypeScript 流程控制语法知识点及案例代码(4)
  • Docker镜像和容器有什么区别
  • NDK19无法在AppleM芯片运行解决方案
  • 深入C++的set集合:用法、特性与应用实例
  • 2025 家用投影新标杆:雷克赛恩 CyberPro1 如何重新定义客厅观影体验
  • 新京东,正在成为一种生活方式
  • Transformer网络结构
  • 【笔记】 huggingface.co:443是连接出错吗
  • Node.js 实战二:接口参数校验与类型安全方案
  • 主打「反激进」的一汽丰田,靠稳扎稳打的技术实现突围
  • 实战记录:Java 高并发插入 MySQL 唯一索引表引发死锁的排查与解决
  • Windows 本地部署MinerU详细教程
  • 厂房气楼做法
  • [Lc] 5.16 One question a day周总结
  • 项目管理进阶:全文解读企业IT系统全生命周期管理与运营平台建设方案【附全文阅读】
  • 【RTMP】RTMP协议的详细介绍
  • SpringBoot3.4.5下Lombok的@Data注解不生效,解决方案
  • Gmsh 读取自定义轮廓并划分网格:深入解析与实践指南