mvc结构:

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

jar包:

dbcp配置文件:

  1. driverClassName=com.mysql.jdbc.Driver
  2. url=jdbc:mysql://localhost:3306/zhl
  3. username=root
  4. password=root
  5.  
  6. initialSize=10
  7.  
  8. maxActive=50
  9.  
  10. maxIdle=20
  11.  
  12. minIdle=5
  13.  
  14. maxWait=60000
  15.  
  16. connectionProperties=useUnicode=true;characterEncoding=utf8
  17.  
  18. defaultAutoCommit=true
  19.  
  20. defaultReadOnly=
  21.  
  22. defaultTransactionIsolation=REPEATABLE_READ

DBCPUti类:

  1. package com.chensi.test;
  2.  
  3. import java.io.InputStream;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.Properties;
  9.  
  10. import javax.sql.DataSource;
  11.  
  12. import org.apache.commons.dbcp.BasicDataSourceFactory;
  13.  
  14. public class DBCPUtil {
  15. private static DataSource ds;
  16.  
  17. public static DataSource getDs() {
  18. return ds;
  19. }
  20. public static void setDs(DataSource ds) {
  21. DBCPUtil.ds = ds;
  22. }
  23. static{
  24. try {
  25. InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
  26. Properties props = new Properties();
  27. props.load(in);
  28. ds = BasicDataSourceFactory.createDataSource(props);
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. public static Connection getConnection(){
  34. try {
  35. return ds.getConnection();
  36. } catch (SQLException e) {
  37. throw new RuntimeException(e);
  38. }
  39. }
  40. public static void release(ResultSet rs,Statement stmt,Connection conn){
  41. if(rs!=null){
  42. try {
  43. rs.close();
  44. } catch (SQLException e) {
  45. e.printStackTrace();
  46. }
  47. rs = null;
  48. }
  49. if(stmt!=null){
  50. try {
  51. stmt.close();
  52. } catch (SQLException e) {
  53. e.printStackTrace();
  54. }
  55. stmt = null;
  56. }
  57. if(conn!=null){
  58. try {
  59. conn.close();
  60. } catch (SQLException e) {
  61. e.printStackTrace();
  62. }
  63. conn = null;
  64. }
  65. }
  66. }

业务代码:

实体类账户类:

  1. package com.chensi.domain;
  2.  
  3. public class Account {
  4.  
  5. private String Id;
  6. private String name;
  7. private int money;
  8. public String getId() {
  9. return Id;
  10. }
  11. public void setId(String id) {
  12. Id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public int getMoney() {
  21. return money;
  22. }
  23. public void setMoney(int money) {
  24. this.money = money;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Account [Id=" + Id + ", name=" + name + ", money=" + money + "]";
  29. }
  30. }

dao层:

  1. package com.chensi.dao.impl;
  2.  
  3. import java.sql.SQLException;
  4.  
  5. import org.apache.commons.dbutils.DbUtils;
  6. import org.apache.commons.dbutils.QueryRunner;
  7. import org.apache.commons.dbutils.handlers.BeanHandler;
  8.  
  9. import com.chensi.dao.TransformDao;
  10. import com.chensi.domain.Account;
  11. import com.chensi.test.DBCPUtil;
  12.  
  13. import com.chensi.utils.ManagerThreadLocal;
  14.  
  15. public class TransformDaoImpl implements TransformDao {
  16.  
  17. public Account findAccountByUsername(String username) throws SQLException {
  18. QueryRunner queryRunner = new QueryRunner(DBCPUtil.getDs());
  19. Account account = queryRunner.query(ManagerThreadLocal.getConnection(),"select * from Account where name=?", new BeanHandler<Account>(Account.class),username);
  20. return account;
  21. }
  22.  
  23. public void TransfromMoney(Account account) throws SQLException {
  24. QueryRunner queryRunner = new QueryRunner(DBCPUtil.getDs());
  25. queryRunner.update(ManagerThreadLocal.getConnection(),"update account set money=? where name=?",account.getMoney(),account.getName());
  26. }
  27. }

service层:

  1. package com.chensi.service.impl;
  2.  
  3. import java.sql.SQLException;
  4.  
  5. import com.chensi.dao.TransformDao;
  6. import com.chensi.dao.impl.TransformDaoImpl;
  7. import com.chensi.domain.Account;
  8. import com.chensi.service.TransfromService;
  9. import com.chensi.utils.ManagerThreadLocal;
  10.  
  11. public class TransfromServiceInmpl implements TransfromService {
  12.  
  13. TransformDao dao = new TransformDaoImpl();
  14. //转账的方法
  15. public void tranFromMoney(String fromUsername, String toUserName, int money) throws SQLException {
  16.  
  17. try {
  18. ManagerThreadLocal.startTransaction();
  19. Account fromAccount = dao.findAccountByUsername(fromUsername);
  20. Account toAccount = dao.findAccountByUsername(toUserName);
  21.  
  22. fromAccount.setMoney(fromAccount.getMoney()-money);
  23.  
  24. toAccount.setMoney(toAccount.getMoney()+money);
  25.  
  26. dao.TransfromMoney(toAccount);
  27. dao.TransfromMoney(fromAccount);
  28. ManagerThreadLocal.commit();
  29. } catch (Exception e) {
  30. ManagerThreadLocal.rollback();
  31. }finally{
  32. ManagerThreadLocal.close();
  33. }
  34. }
  35.  
  36. }

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

  1. package com.chensi.controller;
  2.  
  3. import java.sql.SQLException;
  4.  
  5. import org.junit.Test;
  6.  
  7. import com.chensi.service.TransfromService;
  8. import com.chensi.service.impl.TransfromServiceInmpl;
  9.  
  10. public class TransFromController {
  11.  
  12. public static void main(String[] args) throws SQLException {
  13. TransfromService service = new TransfromServiceInmpl();
  14. service.tranFromMoney("zhl", "chensi", 200);
  15. }
  16. }

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

  1. package com.chensi.utils;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.SQLException;
  5.  
  6. import com.chensi.test.DBCPUtil;
  7.  
  8. //用ThreadLocal线程内部类 来控制 取到的connection是一个线程中的connection,这样可以-
  9. //安全的控制事务
  10. public class ManagerThreadLocal {
  11.  
  12. private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
  13.  
  14. //获取到一个连接 (static 是为了 类名. 调用)
  15. public static Connection getConnection(){
  16. Connection conn = tl.get();
  17. if(conn==null){
  18. conn = DBCPUtil.getConnection();
  19. tl.set(conn); //从DBCP线程池中取出一个connn放入到ThreadLocal的Map之中
  20. }
  21. return conn;
  22. }
  23.  
  24. //开启事务
  25. public static void startTransaction(){
  26. Connection connection = getConnection();
  27. try {
  28. connection.setAutoCommit(false); //开启事务 (这个连接是从当前线程取出来的)
  29. } catch (SQLException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. //提交
  34. public static void commit(){
  35. try {
  36. getConnection().commit(); //提交事务
  37. } catch (SQLException e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. //回滚
  42. public static void rollback(){
  43. try {
  44. getConnection().rollback(); //回滚事务
  45. } catch (SQLException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. //释放,也即是将conn从ThreadLocal中的Map中移出出去
  50. public static void close(){
  51. try {
  52. getConnection().close(); //连接关闭,然后将threadLocal中的connection 清除
  53. tl.remove(); //threadLocal(当前线程中清除掉connection)
  54. } catch (SQLException e) {
  55. e.printStackTrace();
  56. }
  57. }
  58.  
  59. }

效果:转账前:

转账之后:

一个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. linux sed 添加 删除 一行

    find . -type f -name "*.lua" | xargs sed -i '1 i \#!\/usr\/bin\/lua' #一行前添加(文件至少有一行) 复制自: ...

  2. C#对DBF文件的操作

    protected void Page_Load(object sender, EventArgs e) { System.Data.Odbc.OdbcConnection conn = new Sy ...

  3. Session操作

    存储API localStorage和sessionStorage通常被当做普通的JavaScript对象使用:通过设置属性来存储字符串值,查询该属性来读取该值.除此之外,这两个对象还提供了更加正式的 ...

  4. <读书笔记>软件调试之道 :问题的核心-如何修复缺陷

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! 修复缺陷 对于一个好的修复来说,不仅仅是让软件运行正确,还需要为将来奠定基础.一 ...

  5. Xena测试仪的自动化

    Xena,Xena Networks公司的网络测试仪,也能覆盖以太网L2~L7层测试仪,但功能较简单,界面也很简洁,用起来比较直观方便. 1.Xena的自动化测试场景 测试PC上的AT框架--> ...

  6. WPF绘制矢量图形模糊的问题

    WPF默认提供了抗锯齿功能,通过向外扩展的半透明边缘来实现模糊化.由于WPF采用了设备无关单位,当设备DPI大于系统DPI时,可能会产生像素自动扩展问题,这就导致线条自动向外扩展一个像素,并且与边缘相 ...

  7. shellinabox基于web浏览器的终端模拟器

    1. Shellinabox介绍 Shellinabox 是一个利用 Ajax 技术构建的基于 Web 浏览器的远程终端模拟器,也就是说安装了该软件之后,服务器端不需要开启 ssh服务,通过 Web  ...

  8. Linux常用目录及文件

    1./etc/sysconfig/network 操作相关:hostname设置 2./etc/sysconfig/network-scripts/ifcfg-ethX(X为0.1等编号,一般为0) ...

  9. 基于angular写的一个todolist

    对于新手来说,使用angularjs写一个todolist可以快速入门

  10. 基于log4net的支持动态文件名、按日期和大小自动分割文件的日志组件

    最近处理一个日志功能,用log4net的配置不能完全满足要求,所以在其基础上简单封装了一下,支持以下功能: 1 零配置 内置默认配置,引用dll后不需要添加或修改任何配置文件也可以使用 2 动态指定文 ...