java mysql多次事务 模拟依据汇率转账,并存储转账信息 分层完成 dao层 service 层 client层 连接池使用C3p0 写入库使用DBUtils
Jar包使用,及层的划分

c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置
默认配置最常用 建议放在最开头。
放其他地方也没问题
-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test2</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
<user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides>
</default-config> </c3p0-config>
JDBCUtils
package cn.itcast.tools; import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; /*a). 私有,静态成员变量:ComboPooledDataSource 并创建对象;加载配置文 件的默认配置。 b). 公有,静态成员方法:public static DataSource getDataSource(),此方法返 回C3P0连接池对象; c). 公有,静态成员方法:public static Connection getConnection(),此方法返回 通过C3P0连接池获取的Connection对象;使用本地线程 ThreadLocal*/ public class JDBCUtils { private static ComboPooledDataSource dataSource =new ComboPooledDataSource(); private static ThreadLocal<Connection> local=new ThreadLocal<Connection>(); public static DataSource getDataSource() { return dataSource; } public static Connection getConnection(){ Connection con=local.get();
if(con==null) {
try {
con=dataSource.getConnection();
local.set(con);
} catch (SQLException e) {
e.printStackTrace();
}
con=local.get();
}
return con; } public static void close(Connection con,Statement st,ResultSet rs) { if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
dao
package com.swift.dao; import java.sql.Connection;
import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.itcast.domain.Account;
import cn.itcast.tools.JDBCUtils; public class Dao { private QueryRunner qr = new QueryRunner();
private Connection con=JDBCUtils.getConnection(); public void querySenderBalance(String cardid1, double money) throws SQLException { String sql = "SELECT * FROM account WHERE cardid=?;";
BeanHandler<Account> rsh = new BeanHandler<Account>(Account.class);
Account bean = qr.query(con, sql, rsh, cardid1);
System.out.println(bean);
double balance = bean.getBalance();
System.out.println(balance);
if (balance < money) {
System.out.println("余额不足!");
System.exit(0);
} else {
System.out.println("余额足够了!");
}
} public int zhuanchu(String cardid, double money) throws SQLException { String chaxun = "select moneyRate from account where cardid=?";
double rate=(double) qr.query(con,chaxun, new ScalarHandler(),cardid);
double moneyRate=money*rate/100;
System.out.println(moneyRate);
String shengyu = "UPDATE account SET balance =balance-?-? WHERE cardid=?;";
return qr.update(con, shengyu, money,moneyRate,cardid); }
public int zhuanru(String cardid, double money) throws SQLException { String zengjia = "UPDATE account SET balance =balance+? WHERE cardid=?;";
return qr.update(con, zengjia, money,cardid); }
public int writeInfo(String cardid, String tratype,double money,String tradate) throws SQLException { String info = "insert into transaction(cardid,tratype,tramoney,tradate) values(?,?,?,?);";
return qr.update(con, info, cardid,tratype,money,tradate); } }
Service
package com.swift.service; import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date; import com.swift.dao.Dao; import cn.itcast.tools.JDBCUtils; public class Service { private Connection con=JDBCUtils.getConnection(); public void transfer(String cardid1, String cardid2, double money) { try { con.setAutoCommit(false);
Dao dao=new Dao();
dao.querySenderBalance(cardid1, money);
int chu=dao.zhuanchu(cardid1, money);
int ru=dao.zhuanru(cardid2, money);
con.commit();
if(chu>0&&ru>0) {
System.out.println("转账成功.");
}
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String tradate=sdf.format(date);
dao.writeInfo(cardid1, "转出", money, tradate);
dao.writeInfo(cardid2, "转入", money, tradate);
con.commit();
} catch (Exception e) {
System.out.println("出现异常准备回滚.");
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
}
client
package com.swift.client;
import com.swift.service.Service;
public class Client {
public static void main(String[] args) {
String cardid1 = "6212999999999";
String cardid2 = "6212888888888";
double money = 600;
Service s=new Service();
s.transfer(cardid1, cardid2, money);
}
}
java mysql多次事务 模拟依据汇率转账,并存储转账信息 分层完成 dao层 service 层 client层 连接池使用C3p0 写入库使用DBUtils的更多相关文章
- HDFS的Java客户端操作代码(查看HDFS下所有的文件存储位置信息)
1.查看HDFS下所有的文件存储位置信息 package Hdfs; import java.net.URI; import org.apache.hadoop.conf.Configuration; ...
- java+mysql实现保存图片到数据库,以及读取数据库存储的图片
一:建表 二:获取数据库连接 1:导入mysql的驱动jar包,mysql-connector-java-5.1.8-bin.jar 2:写代码连接数据库,如下: /** * */ package c ...
- jdbc连接池中c3p0的配置文件的详解以及在在java中如何使用
<c3p0-config> <!-- 默认配置,如果没有指定则使用这个配置 --> <default-config> <property name=" ...
- hibernate+mysql的连接池配置
1:连接池的必知概念 首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...
- Java Web(十) JDBC的增删改查,C3P0等连接池,dbutils框架的使用
前面做了一个非常垃圾的小demo,真的无法直面它,菜的抠脚啊,真的菜,好好努力把.菜鸡. --WH 一.JDBC是什么? Java Data Base Connectivity,java数据库连接,在 ...
- JAVA中事物以及连接池
一.事物 什么是事物? 事务,一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元.这些单元要么全都成功,要么全都不成功. 做一件事情,这个一件事情中有多个 ...
- 十三、事务、连接池 、ThreadLocal 、BaseServlet自定义Servlet父类 、 DBUtils à commons-dbutils
l 事务 l 连接池 l ThreadLocal l BaseServlet自定义Servlet父类(只要求会用,不要求会写) l DBUtils à commons-dbutils 事务 l 事务的 ...
- 超全面的JavaWeb笔记day18<事务&连接池&DBUtils>
1.事务 ACID 原子性 一致性 隔离性 持久性 mysql中开启和关闭事务 开启事务:START TRANSACTION 结束事务 提交事务:COMMIT 回滚事务:ROLLBACK JDBC中开 ...
- day18(JDBC事务&连接池介绍&DBUtils工具介绍&BaseServlet作用)
day18总结 今日思维导图: 今日内容 事务 连接池 ThreadLocal BaseServlet自定义Servlet父类(只要求会用,不要求会写) DBUtils à commons-dbuti ...
随机推荐
- vue router-link 添加在定义事件
在vue学习中遇到给router-link 标签添加事件@click .@mouseover等无效的情况 我想要做的是v-for遍历出来的选项卡, 鼠标移上去出现删除标签,移除标签消失的效果 原代码: ...
- [转]JS对JSON的操作总结
本文转自:http://www.cnblogs.com/csj222/archive/2013/04/11/3013667.html 对于前端完全是菜鸟,迫于无奈,工作中要用到JS,尤其对JSON的处 ...
- jquery中beforeSend和complete的使用 --- 提高用户体验&&设置请求头
beforeSend方法的用户主要有下面几个: 第一:用于在发送ajax请求之前设置请求头 即作为前端,如果我们希望在发送数据之前设置请求头,就可以像下面这么做: beforeSend: functi ...
- Cloudera Kudu是什么?
不多说,直接上干货! Cloudera Kudu是什么? kudu是cloudera在2012开始秘密研发的一款介于hdfs和hbase之间的高速分布式列式存储数据库.兼具了hbase的实时性.hdf ...
- RadControl使用相同的Theme
我們僅須對兩個地方加一些程式碼,就可使所有的RadControl擁用相的Theme,如此一下不但可使Ap內布景主題一致,設計者亦不需要對每個控件做字型,顏色,大小等等瑣碎的設計. App.Xaml.c ...
- pat1033. To Fill or Not to Fill (25)
1033. To Fill or Not to Fill (25) 时间限制 10 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 ZHANG, Gu ...
- asp.net用zip方法批量导出txt
首先: 引用 ICSharpCode.SharpZipLib.dll,百度下载 然后引用命名空间: using ICSharpCode.SharpZipLib.Zip;using ICSharpCod ...
- Java—多态
多态——对象的多种形态(继承是多态实现的基础) 引用多态:父类的引用可以指向本类的对象:父类的引用可以指向子类的对象 方法多态:创建本类对象时,调用的方法为本类方法:创建子类对象时,调用的方法为子类重 ...
- 非常全面的PHP header函数设置HTTP头的示例
突然看到这个,觉得很好,就拿过来了,如下: //定义编码 header( 'Content-Type:text/html;charset=utf-8 '); //Atom header('Conten ...
- golang 2行代码在基于arm linux的树莓派、orangepi上运行http web服务
go语言(golang)简化了跨平台交叉编译步骤,支持在windows系统下交叉编译基于arm+linux平台的应用,运行时无需其它依赖库.以下以一个简单的http server为例,先上源码: ** ...