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

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

需要使用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. 集群服务器状态命令------rs.status()各个字段的含义

    可根据rs.status() 查询集群服务器状态.字段解释: self 这个信息出现在执行rs.status()函数的成员信息中 stateStr用户描述服务器状态的字符串.有SECONDARY,PR ...

  2. MySQL Infobright 数据仓库快速安装笔记[转]

    [文章作者:张宴 本文版本:v1.1 最后修改:2010.05.18 转载请注明原文链接:http://blog.zyan.cc/infobright/] Infobright是一个与MySQL集成的 ...

  3. Asp.net mvc4 快速入门之构建表单

    1.asp.net mvc4  Index.cshtml页面上构建表单form的方式 @{ ViewBag.Title = "Index"; Layout = "~/Vi ...

  4. sort_action

    li, r = [23,8, 45, 5, 0, -6, 745,8, 8], [] while (len(li) > 0): loop_, min, tag = len(li), li[0], ...

  5. 修改JDK环境变量,不生效的问题

    一般是在/etc/profile下面配置JDK的环境变量 JAVA_HOME=/data/jdk1.7.0_72 JRE_HOME=/data/jdk1.7.0_72/jre PATH=$PATH:$ ...

  6. 关于hibernate配置步骤

    1.导入jar包,根据连接数据库不同改变数据库jar包 2.创建hibernate.cfg.xml文件 几个常用的参数作用: connection.url:表示数据库URL,不同数据库有不同写法 a. ...

  7. CentOS-7-64bit 下为firefox安装flashplayer

    最近更新了Centos 7 还是有一些不习惯的 给ff安flashplayer插件时,按centos 6.x的方法时都无法成功,后来find了一下,才知道firefox还有一个64bit的文件夹: 解 ...

  8. iOS 判定string是不是中文字符

    +(BOOL)IsChinese:(NSString *)str { ; i< [str length];i++) { int a = [str characterAtIndex:i]; if( ...

  9. 安装MySQLdb出现的问题

    枫竹梦的环境是自己编译安装的MySQL,安装目录在/usr/local/mysql. 下载MySQLdb,由于网络上大多数的链接都是指向比较老的sourceforge上,而我们安装最新的1.2.5,h ...

  10. Python对象拷贝——深拷贝与浅拷贝

    对象赋值 浅拷贝 深拷贝 1. 对象赋值 对象的赋值实际上是对对象的引用.也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用.如: >>> t1 = tuple('furzoom ...