每个连接都有自己的独立事务,会造成数据的不一致

这组操作应该要么一起操作成功,要么一起操作失败, 应该使用同一个连接,只有一个能控制事务的对象

需要使用ThreadLocal对象把Connection和当前线程绑定, 从而使一个线程中只有一个能控制事务的对象

关于ThreadLocal: Java并发编程:深入剖析ThreadLocal

事务控制应该都是在业务层

创建一个连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定

/**
* 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定
*/
public class ConnectionUtils { private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
private DataSource dataSource; public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} /**
* 获取当前线程上的连接
* @return
*/
public Connection getThreadConnection() {
try{
//1.先从ThreadLocal上获取
Connection conn = tl.get();
//2.判断当前线程上是否有连接
if (conn == null) {
//3.从数据源中获取一个连接,并且存入ThreadLocal中
conn = dataSource.getConnection();
tl.set(conn);
}
//4.返回当前线程上的连接
return conn;
}catch (Exception e){
throw new RuntimeException(e);
}
} /**
* 把连接和线程解绑
*/
public void removeConnection(){
tl.remove();//remove()用来移除当前线程中变量的副本
  } 
}

和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接

 /**
* 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
*/
public class TransactionManager { private ConnectionUtils connectionUtils; public void setConnectionUtils(ConnectionUtils connectionUtils) {
this.connectionUtils = connectionUtils;
} /**
* 开启事务
*/
public void beginTransaction(){
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
}catch (Exception e){
e.printStackTrace();
}
} /**
* 提交事务
*/
public void commit(){
try {
connectionUtils.getThreadConnection().commit();
}catch (Exception e){
e.printStackTrace();
}
} /**
* 回滚事务
*/
public void rollback(){
try {
connectionUtils.getThreadConnection().rollback();
}catch (Exception e){
e.printStackTrace();
}
} /**
* 释放连接
*/
public void release(){
try {
connectionUtils.getThreadConnection().close();//还回连接池中
52 connectionUtils.removeConnection();
}catch (Exception e){
e.printStackTrace();
}
}
}
 public class AccountDaoImpl implements IAccountDao {

     private QueryRunner runner;
private ConnectionUtils connectionUtils; public void setRunner(QueryRunner runner) {
this.runner = runner;
} public void setConnectionUtils(ConnectionUtils connectionUtils) {
this.connectionUtils = connectionUtils;
} public List<Account> findAllAccount() {
try{
return runner.query(connectionUtils.getThreadConnection(),"select * from account",new BeanListHandler<Account>(Account.class));
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}

(未使用AOP)使用ThreadLocal对象把Connection和当前线程绑定, 从而使一个线程中只有一个能控制事务的对象的更多相关文章

  1. .NET Linq获取一个集合中的一个或多个属性,赋值到新的类对象

    //得到自定义的list var list = schoolGradeClassModelList.Select(x => new DropDownListData() { DataTextFi ...

  2. Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限

    一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...

  3. js delete删除对象属性,delete删除不了变量及原型链中的变量

    js delete删除对象属性,delete删除不了变量及原型链中的变量 一.delete删除对象属性 function fun(){ this.name = 'gg'; } var obj = ne ...

  4. 在 WPF 中获取一个依赖对象的所有依赖项属性

    原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...

  5. 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块

    Log4a 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块 github地址 : https://github.com/EalenXie/log4a 在API每次被请求时 ...

  6. 基于AOP和ThreadLocal实现日志记录

    基于AOP和ThreadLocal实现的一个日志记录的例子 主要功能实现 : 在API每次被请求时,可以在整个方法调用链路中记录一条唯一的API请求日志,可以记录请求中绝大部分关键内容.并且可以自定义 ...

  7. spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析

    知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...

  8. threadlocal精髓是为每一个线程保证一个共享对象,保证一个,保证是同一个

    threadlocal精髓是为每一个线程保证一个共享对象,保证一个,保证同一个线程中是同一个共享对象. 如果是静态变量是共享的话,那必须同步,否则尽管有副本,还是会出错,故C错

  9. [JCIP笔记] (三)如何设计一个线程安全的对象

    在当我们谈论线程安全时,我们在谈论什么中,我们讨论了怎样通过Java的synchronize机制去避免几个线程同时访问一个变量时发生问题.忧国忧民的Brian Goetz大神在多年的开发过程中,也悟到 ...

随机推荐

  1. UVA - 11827 - Maximum GCD,10200 - Prime Time (数学)

    两个暴力题.. 题目传送:11827 Maximum GCD AC代码: #include <map> #include <set> #include <cmath> ...

  2. CIDR(无类域间路由)(转载)

    来源:百度百科 CIDR(无类型域间选路,Classless Inter-Domain Routing)是一个在Internet上创建附加地址的方法,这些地址提供给服务提供商(ISP),再由ISP分配 ...

  3. java线程中断[interrupt()函数] (转载)

    一个正常的线程中断: 从运行到真正的结束,应该有三个阶段: 正常运行. 处理结束前的工作,也就是准备结束. 结束退出. Java曾经提供过抢占式限制中断,但问题多多,例如的Thread.stop.另一 ...

  4. EasyDarwin开源流媒体服务器gettimeofday性能优化(3000万/秒次优化至8000万次/秒)

    -本文由EasyDarwin开源团队成员贡献 一.问题描述 Easydarwin中大量使用gettimeofday来获取系统时间,对系统性能造成了一定的影响.我们来做个测试: While(1) { G ...

  5. java集合类学习心得

    java集合类学习心得 看了java从入门到精通的第十章,做个总结,图片均取自网络. 常用集合的继承关系 Linked 改快读慢 Array 读快改慢 Hash 两都之间 Collection是集合接 ...

  6. Java之运行时异常与编译时异常区别

    Java中用2种方法处理异常: 1.在发生异常的地方直接处理: 2.将异常抛给调用者,让调用者处理. Java异常可分为3种: (1)编译时异常:Java.lang.Exception (2)运行期异 ...

  7. 九度OJ 1129:Skew数 (大数运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:734 解决:548 题目描述: 在 skew binary表示中, 第 k 位的值xk表示xk*(2k+1-1).  每个位上的可能数字是0 ...

  8. 九度OJ 1085:求root(N, k) (迭代)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1407 解决:523 题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k).N'为N的 ...

  9. javascript --- 声明提前(学习笔记)

    声明提升 未声明变量 console.log(a); 在没有定义 a 的情况下,直接使用,会报错. 声明变量 console.log(a); var a = 2; 输出结果:undefined 并不会 ...

  10. imagemap的推荐使用方法,前端自适应image maps库

    1.map在浏览器的兼容性相对来说是比较好的,这是我在项目中的一个处理方法 推荐到下面网站去画map http://imagemap-generator.dariodomi.de/ 2.画完去gith ...