mvc结构:

准备阶段:jar包 ,dbcpconfig.propertie(数据源配置文件 ) ,DBCPUtil。

jar包:

dbcp配置文件:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/zhl
username=root
password=root initialSize=10 maxActive=50 maxIdle=20 minIdle=5 maxWait=60000 connectionProperties=useUnicode=true;characterEncoding=utf8 defaultAutoCommit=true defaultReadOnly= defaultTransactionIsolation=REPEATABLE_READ

DBCPUti类:

package com.chensi.test;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class DBCPUtil {
private static DataSource ds; public static DataSource getDs() {
return ds;
}
public static void setDs(DataSource ds) {
DBCPUtil.ds = ds;
}
static{
try {
InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties props = new Properties();
props.load(in);
ds = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
return ds.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

业务代码:

实体类账户类:

package com.chensi.domain;

public class Account {

    private String Id;
private String name;
private int money;
public String getId() {
return Id;
}
public void setId(String id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
@Override
public String toString() {
return "Account [Id=" + Id + ", name=" + name + ", money=" + money + "]";
}
}

dao层:

package com.chensi.dao.impl;

import java.sql.SQLException;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.chensi.dao.TransformDao;
import com.chensi.domain.Account;
import com.chensi.test.DBCPUtil; import com.chensi.utils.ManagerThreadLocal; public class TransformDaoImpl implements TransformDao { public Account findAccountByUsername(String username) throws SQLException {
QueryRunner queryRunner = new QueryRunner(DBCPUtil.getDs());
Account account = queryRunner.query(ManagerThreadLocal.getConnection(),"select * from Account where name=?", new BeanHandler<Account>(Account.class),username);
return account;
} public void TransfromMoney(Account account) throws SQLException {
QueryRunner queryRunner = new QueryRunner(DBCPUtil.getDs());
queryRunner.update(ManagerThreadLocal.getConnection(),"update account set money=? where name=?",account.getMoney(),account.getName());
}
}

service层:

package com.chensi.service.impl;

import java.sql.SQLException;

import com.chensi.dao.TransformDao;
import com.chensi.dao.impl.TransformDaoImpl;
import com.chensi.domain.Account;
import com.chensi.service.TransfromService;
import com.chensi.utils.ManagerThreadLocal; public class TransfromServiceInmpl implements TransfromService { TransformDao dao = new TransformDaoImpl();
//转账的方法
public void tranFromMoney(String fromUsername, String toUserName, int money) throws SQLException { try {
ManagerThreadLocal.startTransaction();
Account fromAccount = dao.findAccountByUsername(fromUsername);
Account toAccount = dao.findAccountByUsername(toUserName); fromAccount.setMoney(fromAccount.getMoney()-money); toAccount.setMoney(toAccount.getMoney()+money); dao.TransfromMoney(toAccount);
dao.TransfromMoney(fromAccount);
ManagerThreadLocal.commit();
} catch (Exception e) {
ManagerThreadLocal.rollback();
}finally{
ManagerThreadLocal.close();
}
} }

controller层(测试用的,所以写的比较简单):

package com.chensi.controller;

import java.sql.SQLException;

import org.junit.Test;

import com.chensi.service.TransfromService;
import com.chensi.service.impl.TransfromServiceInmpl; public class TransFromController { public static void main(String[] args) throws SQLException {
TransfromService service = new TransfromServiceInmpl();
service.tranFromMoney("zhl", "chensi", 200);
}
}

控制线程安全的类(自己实现的线程内部类)

package com.chensi.utils;

import java.sql.Connection;
import java.sql.SQLException; import com.chensi.test.DBCPUtil; //用ThreadLocal线程内部类 来控制 取到的connection是一个线程中的connection,这样可以-
//安全的控制事务
public class ManagerThreadLocal { private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); //获取到一个连接 (static 是为了 类名. 调用)
public static Connection getConnection(){
Connection conn = tl.get();
if(conn==null){
conn = DBCPUtil.getConnection();
tl.set(conn); //从DBCP线程池中取出一个connn放入到ThreadLocal的Map之中
}
return conn;
} //开启事务
public static void startTransaction(){
Connection connection = getConnection();
try {
connection.setAutoCommit(false); //开启事务 (这个连接是从当前线程取出来的)
} catch (SQLException e) {
e.printStackTrace();
}
}
//提交
public static void commit(){
try {
getConnection().commit(); //提交事务
} catch (SQLException e) {
e.printStackTrace();
}
}
//回滚
public static void rollback(){
try {
getConnection().rollback(); //回滚事务
} catch (SQLException e) {
e.printStackTrace();
}
}
//释放,也即是将conn从ThreadLocal中的Map中移出出去
public static void close(){
try {
getConnection().close(); //连接关闭,然后将threadLocal中的connection 清除
tl.remove(); //threadLocal(当前线程中清除掉connection)
} catch (SQLException e) {
e.printStackTrace();
}
} }

效果:转账前:

转账之后:

一个MVC架构的线程安全的银行转账案例(事务控制)的更多相关文章

  1. 关于一个mvc架构的cms的后台getshell

    都知道,mvc的话 除了根目录还有public目录可以访问,其他的访问都是不行的,因为会默认都是会解析url 然后我们来看今天的猪脚 大概的图片上传还有远程文件加载我黑盒测过了  就是想捞一个快一点的 ...

  2. 一个初学者对于MVC架构的理解

    我很早之前就开始接触.NET开发,一直都在2.0的框架下,所以对于MVC这种架构,听说过,但没有具体使用过,近期和外部朋友接触时,有了解到他们公司在使用MVC这种架构,所以自己就找来相关资料了解一下M ...

  3. MVC架构学习

    作为一名小小的GreenBird,学习MVC呢,已经花费了2天了,期间得到了美丽的学姐的帮助,初步整理了一下. 首先,学习MVC呢就先以一个标准的MVC的简单的例子来入手,然后根据学姐的PPT,我用v ...

  4. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  5. RxHttp - 轻量级、可扩展、易使用、完美兼容MVVM、MVC架构的网络封装类库

    前言 RxHttp是基于RxJava2+Retrofit 2.9.0+OkHttp 4.9.0实现的轻量级,完美兼容MVVM架构的网络请求封装类库,小巧精致,简单易用,轻轻松松搞定网络请求. GitH ...

  6. 【JAVA】基于MVC架构Java技术荟萃案例演练

    基于JAVA-MVC技术的顾客管理项目案例总结 作者 白宁超 2016年6月9日22:47:08 阅读前瞻:本文源于对javaweb相关技术和资料汇总,涉及大量javaweb基础技术诸如:Servle ...

  7. Android 四大组件 与 MVC 架构模式

    作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是 ...

  8. MVC架构模式分析与设计(一)---简单的mvc架构

    首先 我要感谢慕课网的老师提供视频资料 http://www.imooc.com/learn/69 下面我来进行笔记 我们制作一个简单的mvc架构 制作第一个控制器 testController.cl ...

  9. IntelliMVCCode智能MVC架构的代码助手使用方法

    智能代码生成工具,快速帮助开发者提升开发速度,通过工具自动生成MVC架构的大量源代码,节省更多的开发时间. 工具使用的框架:.net4.0,通过工具连接到数据库自动提取数据表或视图中的结构,生成对应的 ...

随机推荐

  1. DAO模式设计步骤

    1.DAO 全称是data access object,数据库访问对象,主要的功能就是用于进行数据操作的,在程序的标准开发架构中属于数据层的操作. 2.分成架构 企业分层架构 客户层:因为现在都采用了 ...

  2. 二模14day2解题报告

    T1.砍树(cuttree) 给出n棵树,要锯下m米木材,现在有一个高度h,h以上所有木头都砍下来,求满足m米的最小h 很简单的二分答案判断可行性. T2.快速求和(quicksum) 给出数字串s, ...

  3. .net网站能走多远

    刚写好了学校网站,请大家帮忙测试一下.不知道怎么sql注入,或者DDoS攻击,我也是大四什么都是摸索阶段,不过这个网站 做了好长时间了,现在终于可以上架了,希望大家能指点一二,谢谢! 地址:http: ...

  4. JS循环往table中写入行

    < script > $(function() { $('#test').click(function() { $.ajax({ url: '__APP__/Article/jsonTes ...

  5. Dalvik系列02 - 指令格式

    简介 该文档描述了Dalvik 可执行文件和Dalvik 字节码的指令格式. 按照位的描述 格式描述表(见下文)的第一列表示个格式的位结构,它由一个或者多个由空格分开的“指令单元”构成,每个指令单元的 ...

  6. Windows内核原理系列01 - 基本概念

    1.Windows API Windows 应用编程接口(API)是针对WIndwos操作系统用户模式的系统编程接口,包含在WindwosSDK中. 2.关于.NET .NET由一个被称为FCL的类库 ...

  7. html5 placeholder ie 不兼容问题 解决方案

    解决HTML5 placeholder的方案 来源:   时间:2013-09-05 20:06:49   阅读数:11375 分享到: 0 [导读] 使低版本浏览器支持Placeholder有很多方 ...

  8. make[2]: *** No rule to make target `/root/.pyenv/versions/anaconda3-2.4.0/lib/libpython3.5m.so', needed by `evaluation.so'. Stop.

    当出现No rule to make target ,肯定是Makefile有问题. 有的makefile是脚本生成的,你得看脚本的配置文件对不对. 我的是这个脚本生成的.发现是Pythondir的配 ...

  9. DOM Document

    1.DOM Document对象 定义:每个载入浏览器的 HTML 文档都会成为 Document 对象.Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问. Docume ...

  10. TextView实现歌词同步

    利用TextView实现歌词同步显示,这是一个简单的利用TextView实现滚动实时显示歌词的. 里面的内容都已经写上了详细的注释.里面播放音乐的时候歌词同步展示. 做媒体这块的朋友可以学习一下,练练 ...