JDBC事务(三)ThreadLocal绑定Connection
处理一个请求即开启一个线程,在三层中,执行三层中的方法都是用的同一个线程。
我们开启一个事务,使用conn.setAutoCommit(false); conn应该属于ado层,不应该出现在service层,但处理事务应该在service层执行。
针对上述矛盾,我们考虑将Connection绑定到ThreadLocal中,因为三层的执行都是在同一个线程,当需要Connection时,从ThreadLocal中取即可。
更改上一章转账按例,结构如下:

更改C3P0线程池的工具类 MyDataSourceUtils
package cn.sasa.util; import java.sql.Connection;
import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class MyDataSourceUtils {
private static DataSource dataSource = new ComboPooledDataSource("mydb"); public static DataSource getDataSource() {
return dataSource;
} public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
} //当前线程
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); // 获得当前线程上绑定的conn
public static Connection getCurrentConnection() throws SQLException {
// 从ThreadLocal找 当前线程是否有对应的Connection
Connection conn = threadLocal.get();
if (conn == null) {
conn = getConnection();
// 将conn绑定到ThreadLocal(map)上
threadLocal.set(conn);
}
return conn;
} // 开启事务
public static void StartTransaction() throws SQLException {
Connection conn = getCurrentConnection();
conn.setAutoCommit(false);
} // 回滚事务
public static void rollback() throws SQLException {
Connection conn = getCurrentConnection();
conn.rollback();
threadLocal.remove();
conn.close();
} // 提交事务
public static void commit() throws SQLException {
Connection conn = getCurrentConnection();
conn.commit();
threadLocal.remove();
conn.close();
}
}
更改service层代码:
package cn.sasa.service; import java.sql.SQLException; import cn.sasa.dao.TransferDao;
import cn.sasa.util.MyDataSourceUtils; public class TransferService { public boolean doTran(String outAccount, String inAccount, double money) {
boolean flag = true; try {
MyDataSourceUtils.StartTransaction(); TransferDao tran = new TransferDao();
int rs1 = tran.doOutAccount(outAccount, money);
int rs2 = tran.doInAccount(inAccount, money); if(rs1<=0 || rs2<=0) {
MyDataSourceUtils.rollback();
flag=false;
} } catch (Exception e) {
flag = false;
try {
MyDataSourceUtils.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
try {
MyDataSourceUtils.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
return flag;
}
}
更改dao层:
package cn.sasa.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import cn.sasa.util.MyDataSourceUtils;
public class TransferDao {
//资金转出
public int doOutAccount( String outAccount, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
String sql = "update account set money=money-? where name=?";
int rs = runner.update(MyDataSourceUtils.getCurrentConnection(), sql, money,outAccount);
return rs;
}
//资金转入
public int doInAccount(String inAccount, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
String sql = "update account set money=money+? where name=?";
int rs = runner.update(MyDataSourceUtils.getCurrentConnection(), sql, money,inAccount);
return rs;
}
}
web层与客户端jsp页面略。
客户端请求一次即开启一个线程,再次请求则开启另一个线程。
JDBC事务(三)ThreadLocal绑定Connection的更多相关文章
- 网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别
1.1.1 API详解:注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 原因有2个: >导致驱动被注册2 ...
- JDBC事务--软件开发三层架构--ThreadLocal
JDBC事务--软件开发三层架构--ThreadLocal 一.JDBC事务 1.概述: 事务是指逻辑上的一组操作!这一组操作,通常认为是一个整体,不可拆分! 特点:同生共死;事务内的这一组操作要么全 ...
- JDBC(三)----JDBC控制事务
## JDBC控制事务 1.事务:一个包含多个步骤的业务操作.如果这个业务员操作被事务管理,则这多个步骤要么同时成功,要么同时失败. 2.操作: 1.开启事务 2.提交事务 3.回滚事务 3.使用C ...
- Mysql事务与JDBC事务管理
一.事务概述 1.什么是事务 一件事情有n个组成单元 要不这n个组成单元同时成功 要不n个单元就同时失败 就是将n个组成单元放到一个事务中 2.mysql的事务 默认的事务:一条sql语句就是一个事务 ...
- JDBC 事务控制
一.简介: 前面一遍提到了jdbc事务相关的概念.从中了解到事务应具有ACID特性.所以对于javaweb开发来说,某一个service层的方法,应该是一个事务,应该是具有原子性的.特别是当一个ser ...
- Java的JDBC事务详解(转)
事务的特性: 1) 原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行. 2) 一致性(consistency):事务在完 ...
- Java的JDBC事务详解
Java的JDBC事务详解 分类: Hibernate 2010-06-02 10:04 12298人阅读 评论(9) ...
- day18(JDBC事务&连接池介绍&DBUtils工具介绍&BaseServlet作用)
day18总结 今日思维导图: 今日内容 事务 连接池 ThreadLocal BaseServlet自定义Servlet父类(只要求会用,不要求会写) DBUtils à commons-dbuti ...
- 分层架构下的纯JDBC事务控制简单解决方案【转】
http://blog.csdn.net/qjyong/article/details/5464835 对目前的JavaEE企业应用开发来说,基本都会采用分层的架构, 这样可以分散关注.松散耦合.逻辑 ...
随机推荐
- IntelliJIdea 2016.2 使用 tomcat 8.5 调试spring的web项目时,bean被实例化两次导致timer和thread被启动了两遍的问题的解决
今天新搭建了一个spring的web项目,项目启动时会启动一个线程,线程里定时执行任务,另外还启动了一个定时器,每秒钟统计系统吞吐量等业务性能数据.但是调试的时候惊奇的发现定时器和线程均被启动了两次. ...
- system generator学习笔记【02】
作者:桂. 时间:2018-05-20 23:28:04 链接:https://www.cnblogs.com/xingshansi/p/9059668.html 前言 继续学习sysgen.接触s ...
- linux安全配置检查脚本_v0.8
脚本环境:RHEL6.* 脚本说明:该脚本作用为纯执行检测不涉及更改配置等操作,与直接上来就改安全配置等基线脚本相比相对安全一些.虽然如此,在你执行该脚本之前仍然建议你备份或快照一下目标系统. 代码部 ...
- SQL格式化插件—SQL Pretty Printer
在SQL Server中我们经常需要编写各种SQL脚本,例如存储过程和函数等,由于在编写过程中,经常会进行调整,格式很乱,可读性很差.对于有强迫症的人来说,看这样的代码非常痛苦,必须要手动对代码进行格 ...
- 使用Mybatis-Generator自动生成Dao、Model、Mapping
Mybatis属于半自动ORM,在使用这个框架中,工作量最大的就是书写Mapping的映射文件,由于手动书写很容易出错,我们可以利用Mybatis-Generator来帮我们自动生成文件. 1.相关文 ...
- SQLServer截取字符串常用函数
SQL Server中一共提供了三个字符串截取函数:LEFT().RIGHT().SUBSTRING(). 一.LEFT()函数 函数说明如下: 语法:LEFT(character,integer). ...
- java 爬取 国税局 省市区级联关系
爬取网址 http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/index.html 因为数据比较大,存储为一个json,会内存溢出. 所以按照每 ...
- Variational RL for POMDP
1.Le, Tuan Anh, et al. "Auto-encoding sequential monte carlo." arXiv preprint arXiv:1705.1 ...
- GraphX学习笔记——Programming Guide
学习的资料是官网的Programming Guide https://spark.apache.org/docs/latest/graphx-programming-guide.html 首先是Gra ...
- springmvc date
数据格式化,从本质上讲属于数据转换的范畴.Spring就是基于数据转换框架植入“格式化”功能的. 在数据转换时我们进行了如下配置: 我们使用的是ConversionServiceFactoryBean ...