1、ThreadLocal该类提供了线程局部变量
2、分析原理:
ThreadLocal内部有一个Map。Map的key是当前线程对象,value是一个Object对象。
模拟该类:
public class ThreadLocal<T>{
private Map<Runnable,T> map = new HashMap<Runnable,T>(); public void set(T t){
map.put(Thread.currentThread(),t);
//把传入的参数绑定到当前线程上
}
public void remove(){
map.remove(Thread.currentThread());
//从当前线程上删除对象
}
public T get(){
return map.get(Thread.currentThread());
//获取当前线程上绑定的对象
}
}
dao层

package com.itheima.dao.impl;

import java.sql.Connection;
import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.utils.TransactionManager;
/** *
*/
public class AccountDaoImpl implements AccountDao {
private QueryRunner qr = new QueryRunner(); @Override
public Account getAccountByName(String accountName) {
try {
Account acc = qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
return acc;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} @Override
public void updateAccount(Account acc) {
try {
qr.update(TransactionManager.getConnection(),"update account set money=? where name=?", acc.getMoney(),acc.getName());
} catch (SQLException e) {
e.printStackTrace();
} } }

service层

package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.dao.impl.AccountDaoImpl;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import com.itheima.utils.TransactionManager;
/**
AOP:Aspect Object Program (面向切面编程 面向方面编程)
名词介绍:
就是将事物的某个方面功能代码抽取出去集中做实现,在需要系统需要用的时候,就将方面代码织入(加入)到系统中,从而实现功能扩展
它打破了原有纵向继承体系结构(代码复用),可以在关键时候横向织入方面代码(代码复用) 实现原理:
动态代理模式 适合场景:事务控制 ,日志控制,权限管理,积分功能
* @author wangli
*
*/
public class AccountServiceImpl implements AccountService { @Override
public void transfor(String sourceAcc, String targetAcc, float money) { AccountDao dao = new AccountDaoImpl();
//1.根据源账户名,得到一个账户对象
Account srcAcc = dao.getAccountByName(sourceAcc);//非常关键,目的是确保dao中用的是同一个Connection对象
//2.目标对象名,得到一 个目标账户
Account tarAcc = dao.getAccountByName(targetAcc);
//3.更新余额
srcAcc.setMoney(srcAcc.getMoney()-money);//源账户减
tarAcc.setMoney(tarAcc.getMoney()+money);//目标账户加 //4.写入到表中
dao.updateAccount(srcAcc);
int i=1/0; dao.updateAccount(tarAcc); } }

threadlocal

package com.itheima.utils;

import java.sql.Connection;
import java.sql.SQLException; /**
* 处理事务 的专门类
* 也就是将这个事务处理的方面分离出来,形成一个独立的类
*
* 就是后面要说的方面代码
* @author wangli
*
*/
public class TransactionManager { private static ThreadLocal<Connection> tL = new ThreadLocal<Connection>();//线程局部变量,用于放入Connection
/**
* 得到连接
* @return
*/
public static Connection getConnection(){
Connection con = tL.get();//从线程局部变量取出一个Connection ----第一次没有值
if(con==null){
//-第一次没有值
con = C3P0Util.getConneciton();//从连接池中取出一个连接
tL.set(con);//放入一个连接到线程局部变量中
}
return con;
} /**
* 开启事务
* @throws Exception
*/
public static void startTransaction() throws Exception{
Connection con = getConnection();
con.setAutoCommit(false);
} /**
* 提交事务
* @throws Exception
*/
public static void commit() throws Exception{
Connection con = getConnection();
con.commit();
} /**
* 回滚事务
* @throws Exception
*/
public static void rollback() throws Exception{
Connection con = getConnection();
con.rollback();
}
}

ThreadLocal 开启事务的更多相关文章

  1. 自定义ThreadLocal和事务(基于自定义AOP)

    参考<架构探险--从零开始写javaweb框架>4.6章节 自定义ThreadLocal package smart; import java.util.Collections; impo ...

  2. 记录一次bug解决过程:resultType和手动开启事务

    一.总结 二.BUG描述:MyBatis中resultType使用 MyBatis中的resultType类似于入参:parameterType.先看IDCM项目中的实际使用案例代码,如下: // L ...

  3. [原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?

    Server version:         5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...

  4. ThinkPHP v3.2.3 数据库读写分离,开启事务时报错:There is no active transaction

    如题:ThinkPHP v3.2.3 数据库读写分离,开启事务时报错: ERR: There is no active transaction 刚开始以为是数据表引擎不对造成的,因为 有几张表的引擎是 ...

  5. 开启事务时mybatis返回主键id

    先说一下没有注解的 先给出实体类: public class City { private int city_id; private String city_name; public int getC ...

  6. 在C#中开启事务

    1.为什么要开启事务: 举一个简单的例子:在银行业务中,有一条记账原则,即又借有贷.为了保证这种原则,每发生一笔银行业务,就必须保证会计账目上借方科目和贷方科目至少个少一笔,并且这两笔要么同时成功,要 ...

  7. Oracle database link中查询会开启事务吗?

    关于oracle database link,使用database link相关的查询语句是否会开启事务呢?我们知道,在数据库中一个简单的SELECT查询语句不会产生事务(select for upd ...

  8. $Django python中使用redis, django中使用(封装了),redis开启事务(管道)

    一 Python操作Redis之普通连接 #先安装 pip3 install redis import redis r = redis.Redis(host='127.0.0.1', port=637 ...

  9. springboot 开启事务以及手动提交事务

    添加依赖,sprongboot 会默认开启事务管理 org.springframework.boot spring-boot-starter-jdbc 在需要的服务类里添加注解 @Autowired ...

随机推荐

  1. <超越死亡:恩宠与勇气>节选

    我有一副身体,但我并非自己的身体.我可以看见并感觉到我的身体,然而凡是可以被看见以及被感觉到的,并不是真正的观者.我的身体也许疲惫或兴奋,生病或健康,沉重或轻松,也可能焦虑或平静,但这与内在的真我全然 ...

  2. C++中四种强制类型转换区别详解

    C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 1.转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非const对 ...

  3. python:格式化输出整数

    import math #default print "PI = %f" % math.pi #width = 10,precise = 3,align = left print ...

  4. 从底层了解ASP.NET体系结构

    导读:  前言  关于ASP.NET的底层的工作机制,最近园子里讨论的甚是火热.相信很多人都看过Rick Strahl先生的一篇经典之作:A low-level Look at the ASP.NET ...

  5. eclipse 链接 hadoop - 问题

    问题:在没有联网时可以连接,当联网时无法链接hdfs 解决:重启hadoop各种守护进程 解析:因该跟host文件中有映射ip有关,有待继续解决......(先留个底)

  6. JavaEE常用开发工具分享

    链接:https://pan.baidu.com/s/1Jxd2Y45LhWAUHc8-dM_ukw 提取码:h50f

  7. 2018沈阳网赛F--上下界网络流

    建图: 首先加一个源点s和汇点t,分别连接在二分图的左边和右边,每条弧的上下界为[L, R],二分图左边和右边之间连弧上下界为[0,1],其实就相当于连弧为1. 然后问题就转换为:有源汇最大流. 继续 ...

  8. vue 用axios实现调用接口下载excel

    了解的方式有两种: 1. 用a标签,href设置为后端提供的excel接口 <a href="excel接口">导出</a> 简单方便,缺点就是当有toke ...

  9. [linux]阿里云主机的免密码登陆安全SSH配置与思考

    公司服务器使用的第三方云端服务,即阿里云,而本地需要经常去登录到服务器做相应的配置工作,鉴于此,每次登录都要使用密码是比较烦躁的,本着极速思想,我们需要配置我们的免登陆. 一 理论概述 SSH介绍 S ...

  10. P4196 [CQOI2006]凸多边形 半平面交

    \(\color{#0066ff}{题目描述}\) 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. \(\color{#0066f ...