项目结构:

数据库:

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.53 : Database - threadlocal
*********************************************************************
*/ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`threadlocal` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `threadlocal`; /*Table structure for table `person` */ DROP TABLE IF EXISTS `person`; CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8; /*Data for the table `person` */ insert into `person`(`id`,`name`) values (12,'ccc'),(13,'ddd'),(15,'ccc'),(16,'ddd'); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

项目代码:

com.gordon.dao:

--SaveDao.java

package com.gordon.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; import com.gordon.domain.Person;
import com.gordon.utils.DataSourceUtil4threadLocal; public class SaveDao { public void add1(Person p) throws SQLException {
String sql = "insert into person (name) values (?)";
Connection connection = DataSourceUtil4threadLocal.getConnection();
PreparedStatement pst = connection.prepareStatement(sql);
pst.setString(1, p.getName());
pst.executeUpdate();
} public void add2(Person p) throws SQLException {
String sql = "insert into person (name) values (?)";
Connection connection = DataSourceUtil4threadLocal.getConnection();
PreparedStatement pst = connection.prepareStatement(sql);
pst.setString(1, p.getName());
pst.executeUpdate();
} }

com.gordon.domain

--Person.java

package com.gordon.domain;

public class Person {
private int id;
private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

com.gordon.service

--SaveService.java

package com.gordon.service;

import java.sql.Connection;
import java.sql.SQLException; import com.gordon.dao.SaveDao;
import com.gordon.domain.Person;
import com.gordon.utils.DataSourceUtil4threadLocal; public class SaveService { public void thread_add(Person p1, Person p2) throws SQLException { Connection connection = DataSourceUtil4threadLocal.getConnection();
DataSourceUtil4threadLocal.startTransaction(); SaveDao saveDao = new SaveDao(); try {
saveDao.add1(p1); //int i = 1 / 0; saveDao.add2(p2); DataSourceUtil4threadLocal.commitTransaction();
} catch (Exception e) {
DataSourceUtil4threadLocal.rollbackTransaction();
e.printStackTrace();
} DataSourceUtil4threadLocal.closeConn(connection);
} public void add(Person p1, Person p2) { SaveDao saveDao = new SaveDao(); try {
saveDao.add1(p1); // int i = 1 / 0; saveDao.add2(p2);
} catch (Exception e) {
e.printStackTrace();
}
}
}

com.gordon.utils

--DataSourceUtil.java

package com.gordon.utils;

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; public class DataSourceUtil {
private static ComboPooledDataSource ds = new ComboPooledDataSource(); /**
* 获取数据源
*
* @return 连接池
*/
public static DataSource getDataSource() {
return ds;
} /**
* 获取连接
*
* @return 连接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
} /**
* 释放资源
*
* @param conn
* 连接
* @param st
* 语句执行者
* @param rs
* 结果集
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
closeResultSet(rs);
closeStatement(st);
closeConn(conn);
} /**
* 释放连接
*
* @param conn
* 连接
*/
public static void closeConn(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
} } /**
* 释放语句执行者
*
* @param st
* 语句执行者
*/
public static void closeStatement(Statement st) {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
} } /**
* 释放结果集
*
* @param rs
* 结果集
*/
public static void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
} }
}

--DataSourceUtil4ThreadLocal.java

package com.gordon.utils;

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; public class DataSourceUtil4threadLocal {
private static ComboPooledDataSource ds = new ComboPooledDataSource(); private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>(); /**
* 获取数据源
*
* @return 连接池
*/
public static DataSource getDataSource() {
return ds;
} /**
* 获取连接
*
* @return 连接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException { Connection connection = threadLocal.get(); if (connection == null) {
connection = ds.getConnection();
threadLocal.set(connection);
} return connection;
} public static void startTransaction() throws SQLException {
Connection connection = getConnection();
if (connection != null) {
connection.setAutoCommit(false);
}
} public static void commitTransaction() throws SQLException {
Connection connection = getConnection();
if (connection != null) {
connection.commit();
}
} public static void rollbackTransaction() throws SQLException {
Connection connection = getConnection();
if (connection != null) {
connection.rollback();
}
} public static void closeConn(Connection conn) {
if (conn != null) {
try {
conn.close();
threadLocal.remove();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
} /**
* 释放资源
*
* @param conn
* 连接
* @param st
* 语句执行者
* @param rs
* 结果集
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
closeResultSet(rs);
closeStatement(st);
closeConn(conn);
} /**
* 释放语句执行者
*
* @param st
* 语句执行者
*/
public static void closeStatement(Statement st) {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
} } /**
* 释放结果集
*
* @param rs
* 结果集
*/
public static void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
} }
}

com.gordon.web.servlet

--SaveServlet.java

package com.gordon.web.servlet;

import java.io.IOException;
import java.sql.SQLException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.gordon.domain.Person;
import com.gordon.service.SaveService; /**
* Servlet implementation class SaveServlet
*/
@WebServlet("/saveServlet")
public class SaveServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { Person p1 = new Person();
p1.setName("ccc"); Person p2 = new Person();
p2.setName("ddd"); // new SaveService().add(p1, p2); // 原始方法 try {
new SaveService().thread_add(p1, p2); // 通过线程绑定连接
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
} }

c3p0-config.xml

<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<!-- 基本配置 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/threadlocal</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>
</default-config> <!-- 命名的配置 -->
<named-config name="itcast">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
<property name="user">root</property>
<property name="password">1234</property> <!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>

java-事务-案例的更多相关文章

  1. 转!!java事务的处理

    java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前 ...

  2. 深入Java事务的原理与应用

    一.什么是JAVA事务    通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 ( ...

  3. java事务的类型——面试被问到

    Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 1.JDBC事务 JDBC 事务是用 Connection 对象控制的.JDBC Conne ...

  4. java事务管理

    一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...

  5. java事务的处理

    java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务. 如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先 ...

  6. JAVA实用案例之水印开发

    写在最前面 上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考. Demo是在我上次写的 JAVA实用案例之文件导入导出(POI方式) 框架基础上 ...

  7. JAVA实用案例之图片水印开发

    写在最前面 上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考. Demo是在我上次写的 JAVA实用案例之文件导入导出(POI方式) 框架基础上 ...

  8. JAVA实用案例之文件导出(JasperReport踩坑实录)

    写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...

  9. 分布式事务(二)Java事务API(JTA)规范

    一.引子 既然出现了分布式场景(DTP模型), 大java也及时制定出一套规范来给各大应用服务器.数据库/mq等厂商使用,以方便管理互通--->JTA闪亮登场.JTA(Java Transact ...

  10. Java 实验案例(多态)

    实验任务 任务一:图形面积周长计算小程序 任务二:饲养员喂养动物程序 实验内容: 任务一: 图形面积周长计算 任务目的: 掌握多态的含义及应用场合 掌握上转型对象和多态的实现 掌握abstract关键 ...

随机推荐

  1. Linux中断 - GIC代码分析

    一.前言 GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器,其architecture specification目前有四个版本,V1-V4(V ...

  2. Python 字典 values() 方法

    描述 Python 字典 values() 方法以列表形式(并非直接的列表,若要返回列表值还需调用list函数)返回字典中的所有值. 语法 values() 方法语法: D.values() 参数 无 ...

  3. Latex文件如何拆分进行独立编译?

    Latex文件如何拆分并进行独立编译? --latex源文件分批独立编译     最近使用Latex编写长文档,对于文件的组织有些困扰.   如果LaTeX文档比较大,可以考虑拆分为几个部分.比如编辑 ...

  4. spring boot 整合 redis

    自己开发环境需要安装 redis 服务,百度一下很多,下面主要说明Springboot 集成 redis 讲解 我的版本 java8 + redis3.0 + springboot 1.5.9. Sp ...

  5. 高效使用 JavaScript 闭包,避免 Node.js 应用程序中的内存泄漏

    在 Node.js 中,广泛采用不同形式的闭包来支持 Node 的异步和事件驱动编程模型.通过很好地理解闭包,您可以确保所开发应用程序的功能正确性.稳定性和可伸缩性. 闭包是一种将数据与处理数据的代码 ...

  6. 由于CentOS的系统安装了epel-release-latest-7.noarch.rpm 导致在使用yum命令时出现Error: xz compression not available问题

    由于CentOS6的系统安装了epel-release-latest-7.noarch.rpm 导致在使用yum命令时出现Error: xz compression not available问题.解 ...

  7. 跟我一起学习VIM - vim插件合集

    2016-06-14 15:04 13333人阅读 评论(0) 收藏 举报 分类: Linux(104)  目录(?)[+]  前两天同事让我在小组内部分享一下VIM,于是我花了一点时间写了个简短的教 ...

  8. perl内置特殊变量查询

    perl中有许多预定于的内置变量,想$_,$,,$>,等等,基本是记不住全部的用法,如果在因特网查阅,有很麻烦,信息不准啦,说的不细啦,但是,万能的perldoc早就帮我们准备好了. 你需要做的 ...

  9. centos升级glibc动态库

    glibc是gnu发布的libc库,即c运行库,glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc.glibc除了封装linux操作系统所提供的系统服务外,它本身也提供 ...

  10. C do {...} while (0) 在宏定义中的作用

    如果你是一名C程序员,你肯定很熟悉宏,它们非常强大,如果正确使用可以让你的工作事半功倍.然而,如果你在定义宏时很随意没有认真检查,那么它们可能使你发狂,浪费N多时间.在很多的C程序中,你可能会看到许多 ...