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企业应用开发来说,基本都会采用分层的架构, 这样可以分散关注.松散耦合.逻辑 ...
随机推荐
- 离线环境下安装ansible,借助有网环境下pip工具
环境 有网的机器(192.168.19.222):rhe65,python2.7.13,pip9.0.1 离线机器(192.168.19.203):rhe65,python2.6 FTP(192.16 ...
- IOS开发中一些受用的编码和调试方法积累
1.## 与 @# 在宏里面该怎样使用 ##的使用, 首先我们添加一个宏 #define LRWeakSelf(type) __weak typeof(type) weak##type = type; ...
- 物联网架构成长之路(27)-Docker练习之Zookeeper安装
0. 前言 准备了解一下消息队列MQ,对比了一些开源的中间件,最后选择Kafka作为以后用到的消息队列,消息队列的应用场景及Kafka与其他消息队列的优缺点这里就不细说了,具体的可以参考其他博客说明. ...
- SQL Server 2016新特性:Temporal Table
什么是系统版本的Temporal Table 系统版本的Temporal Table是可以保存历史修改数据并且可以简单的指定时间分析的用户表. 这个Temporal Table就是系统版本的Tempo ...
- SQL注入学习资料总结
转载自:https://bbs.ichunqiu.com/thread-12105-1-1.html 什么是SQL注入 SQL注入基本介绍 结构化查询语言(Structured Query Lang ...
- Activity的Launch mode详解,A B C D的singleTask模式
本文参考了此文http://hi.baidu.com/amauri3389/blog/item/a54475c2a4b2f040b219a86a.html 另附 android task与back s ...
- 使用Go语言+Protobuf协议完成一个多人聊天室
软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...
- SpringBoot系统列 2 - 配置文件,多环境配置(dev,qa,online)
实现项目的多环境配置的方法有很多,比如通过在Pom.xml中配置profiles(最常见) 然后在Install项目打War包的时候,根据需求打不同环境的包,如图: 这种配置多环境的方法在SSM框架中 ...
- springboot-aop
AOP(面向切面编程)是Spring的两大核心功能之一,功能非常强大,为解耦提供了非常优秀的解决方案. 现在就以springboot中aop的使用来了解一下如何使用aop. 写几个简单的Spring ...
- Android手机用wifi连接adb调试的方法
https://www.jianshu.com/p/dc6898380e38 0x0 前言 Android开发肯定要连接pc的adb进行调试,传统的方法是用usb与pc进行连接,操作简单即插即用,缺点 ...