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企业应用开发来说,基本都会采用分层的架构, 这样可以分散关注.松散耦合.逻辑 ...
随机推荐
- 分析轮子(一)-ArrayList.java
前言:之前也看过一些JDK源码,不过没有留下痕迹,经久年月就淡忘了,现在的时机也差不多了,想再看一次,并且记录下来自己的感想,于是从自己使用最多最熟悉的地方开始!并且看的过程中,我希望自己思考一下如下 ...
- 海外VPS
缘由 国内从ISP拿到的只能是内网IP,当然如今IPv4地址紧张导致的也能够理解,使用免费DDNS能够同样也能将内网通过端口映射将服务发布外网.但是千万不要小瞧了ISP的觉醒,通过限制上行带宽(ADS ...
- Nginx的location匹配规则
一 Nginx的location语法 location [=|~|~*|^~] /uri/ { … } = 严格匹配.如果请求匹配这个location,那么将停止搜索并立即处理此请求 ...
- 在 WPF 中如何在控件上屏蔽系统默认的触摸长按事件
来源:https://stackoverflow.com/questions/5962108/disable-a-right-click-press-and-hold-in-wpf-applicati ...
- XAMARIN上运行IPHONE模拟器
重装农药第32天!!! 今天弄XAMARIN运行IPHONE模拟器,前提是需要MAC 同时在开着,然后打开昨天 建立的HELLO WORLD项目,选择APP1.IOS,直接点右边的三角运行即可,他会自 ...
- Gin框架使用详解
1.什么是Gin Gin是go编写的一个web应用框架. 2.Gin安装 go get github.com/gin-gonic/gin 3.Gin使用示例 package main import ( ...
- Android Studio添加原生库并自动构建
[时间:2017-09] [状态:Open] [关键词:Android,Android Studio,gradle,native,c,c++,cmake,原生开发,ndk-build] 0 引言 最近 ...
- delphi从TRichEdit获得RTF格式文本(PC版本)
function GetRTF(RE: TRichedit): string;varstrStream: TStringStream;beginstrStream := TStringStream.C ...
- iOS中UITextField输入判断小数点后两位
在输入金额的UITextField中,要给予三个规则的判断 1. 只能输入数字(可以通过设置键盘类型为Decimal Pad) 2. 小数点只能有一个 3. 小数点后最多有两位数字 (可以通过正则表达 ...
- mysql密码的坑
一段时间没用本机的mysql,忘了root密码,从网上找的修改方法用起来大多都有问题.mysql版本8.0.12. 网上大多数思路:修改msql启动方式为带--skip-grant-tables参数: ...