一、需求背景:

我们生活经常遇到一个情况:在购买商品的时候,已经支付的了,那么商品应该处于已购买订单里。而不是付款之后,已购买商品没有。

还有转账的时候,转出方和转入方都需要扣减相应的金额,而不是一方减少或者增加。

因为上面的例子都是对数据操作,所以需要我们操作数据库的事务。

如何确定一个事务范围?

事务是由一系列数据库操作组成,他和业务场景有关。当操作完成的时候,如果操作过程没有出现失败,则这个事务产生的数据库操作一并提交(commit)。反之,如果出现失败,则一并回滚(rollback)。

所有事务和业务层(service)确定。

事务的特点:

ACID

   1、原子性:事务里面的操作单元不可切割,要么全部成功,要么全部失败
        2、一致性:事务执行前后,业务状态和其他业务状态保持一致.
        3、隔离性:一个事务执行的时候最好不要受到其他事务的影响
        4、持久性:一旦事务提交或者回滚.这个状态都要持久化到数据库中

不考虑隔离性会出现的读问题:
        脏读:在一个事务中读取到另一个事务没有提交的数据
        不可重复读:在一个事务中,两次查询的结果不一致(针对的update操作)
        虚读(幻读):在一个事务中,两次查询的结果不一致(针对的insert操作)
    通过设置数据库的隔离级别来避免上面的问题(理解)
        read uncommitted      读未提交    上面的三个问题都会出现
        read committed      读已提交    可以避免脏读的发生
        repeatable read        可重复读    可以避免脏读和不可重复读的发生
        serializable        串行化        可以避免所有的问题

两种方式:

1)数据库上控制事务:

默认情况下,mysql数据库中的事务是自动提交。

 mysql> show variables like "%autocommit%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
row in set (0.00 sec

我们可以在数据库上进行事务的开启和关闭。但是这种方式显然不好。

2)java代码实现。

查看connection的方法:

1:void commit() 提交事务。Makes all changes made since the previous commit/rollback permanent and releases any database locks currently held by this Connection object.

2:void  rollback()回滚事务.Undoes all changes made in the current transaction and releases any database locks currently held by this Connection object

3:void setAutocommit(boolean ) false 表示开启事务,true表示事务关闭。Sets this connection's auto-commit mode to the given state.

注意:事务要作用同一个数据库连接。

java代码实现有两种方式:

  1、自上到下传递参数:

    通过service传递到dao层的connection的变量,保证整个过程使用的是同一个数据连接。

  2、当前线程绑定事务:

    通过绑定当前线程一个变量(connection),在dao中获取这个connection,保证整个事务的过程中,使用的是同一个连接。

  其中threadLocal方法:ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID)

    该字段在类中要以private  static 来进行修饰。

    1) T  get() 返回当前线程绑定的值。

    2)void  remove() 从当前线程解绑。

    3)void  set(T  value)  绑定当前线程。

内部实现原理就是map方法对currentThread  进行put 和set  remove。

jdbc工具类:

 package jd.com.tool_jdbc;

 import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory; import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties; public class ds_tool {
private static BasicDataSource ds=null;
private static Connection con=null;
private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
public static BasicDataSource getDs(){
try {
InputStream inp= ds_tool.class.getClassLoader().getResourceAsStream("database.properties");
Properties pro=new Properties();
pro.load(inp);
ds=new BasicDataSourceFactory().createDataSource(pro);
ds.setInitialSize();
ds.setMaxTotal();
ds.setMaxIdle();
return ds;
}catch (Exception ex){
throw new RuntimeException("初始化数据库失败"+ex);
} }
//给当前线程绑定变量。
public static BasicDataSource setDs(){
try {
if(con==null){
ds=getDs();
con=ds.getConnection();
threadLocal.set(con);
}else{
threadLocal.set(con);
}
return ds;
}catch (Exception ex){
ex.printStackTrace();
throw new RuntimeException("初始化错误"+ex);
} }
//开启事务
public static void openEven(){
try {
setDs();
con=threadLocal.get();
con.setAutoCommit(false);
}catch (Exception ex){
ex.printStackTrace();
} }
//提交事务
public static void commEven(){
try {
con=threadLocal.get();
con.commit();
}catch (Exception ex){
ex.printStackTrace();
} }
//回滚事务
public static void rollbackEvent(){
try {
con=threadLocal.get();
System.out.println(con);
con.rollback();
}catch (Exception ex){
ex.printStackTrace();
} }
public static void closedDs(BasicDataSource ds, PreparedStatement pre){
try {
ds.close();
pre.close();
threadLocal.remove();
}catch (Exception ex){
ex.printStackTrace();
} } }

然后在业务层上进行事务的控制。

3)1、queryRunner()初始化的时候,不带参数,是默认是开启事务。

  在执行的时候,update(connection con  sql  object ...parm)传入connection。需要关闭资源 connection。

  2、如果quryRunner(Datasource ds)的时候,内部代码会帮我们实现资源回收。不需要connection.close()

java操作数据库的事务支持的更多相关文章

  1. Java操作数据库——在JDBC里使用事务

    Java操作数据库——在JDBC里使用事务 摘要:本文主要学习了如何在JDBC里使用事务. 使用Connection的事务控制方法 当JDBC程序向数据库获得一个Connection对象时,默认情况下 ...

  2. Java操作数据库——使用连接池连接数据库

    Java操作数据库——使用连接池连接数据库 摘要:本文主要学习了如何使用JDBC连接池连接数据库. 传统方式和连接池方式 传统方式的步骤 使用传统方式在Java中使用JDBC连接数据库,完成一次数据库 ...

  3. Java操作数据库——使用JDBC连接数据库

    Java操作数据库——使用JDBC连接数据库 摘要:本文主要学习了如何使用JDBC连接数据库. 背景 数据持久化 数据持久化就是把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应 ...

  4. Java操作属性文件,支持新增或更新多个属性

    Java操作属性文件.支持新增或更新多个属性 一.更新或新增单个属性的方法 /** * 写入properties信息 * @param filePath 绝对路径(包含文件名称和后缀名) * @par ...

  5. java操作数据库:增删改查

    不多bb了直接上. 工具:myeclipse 2016,mysql 5.7 目的:java操作数据库增删改查商品信息 test数据库的goods表 gid主键,自增 1.实体类Goods:封装数据库数 ...

  6. JDBC 数据库连接 Java操作数据库 jdbc快速入门

    JDBC基本概念 Java DataBase Connectivity 数据库连接 java操作数据库 本质上(sun公司的程序员)定义的一套操作关系型数据库的规则 既接口  更新内容之前 代码 pa ...

  7. JDBC数据源(DataSource)数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。

    JDBC数据源(DataSource)的简单实现   数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 2.数据源提供了一种简单获取数据库连接的方式,并能在内部通 ...

  8. Java操作数据库——手动实现数据库连接池

    Java操作数据库——手动实现数据库连接池 摘要:本文主要学习了如何手动实现一个数据库连接池,以及在这基础上的一些改进. 部分内容来自以下博客: https://blog.csdn.net/soonf ...

  9. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了

    JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...

随机推荐

  1. xshell提示采购解决方法

    参考http://blog.csdn.net/longgeaisisi/article/details/78637179

  2. POJ1284(SummerTrainingDay04-K 原根)

    Primitive Roots Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4505   Accepted: 2652 D ...

  3. lamp配置多个虚拟站点

    在同一ip下添加多个域名站点! 1.查看ip 命令:ifconfig 2.添加域名 命令:vi /etc/hosts 输入域名:如 192.168.160.127   www.test.com 192 ...

  4. 排序算法(1)--Insert Sorting--插入排序[1]--straight insertion sort--直接插入排序

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.基本思想 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成 ...

  5. DNS协议详解

    DNS协议详解 简介 DNS(Domain Name System)域名系统,主要实现的功能是将域名转换成ip地址的一个服务.它是由一个分层的DNS服务器实现的分布式数据库,同时.他也是一个使得主机能 ...

  6. 【读书笔记】iOS-报刊杂志-Newsstand应用编程

    一,使用Newsstand Kit API 苹果公司在iOS5之后提供了电子报刊杂志开发API-Newsstand Kit.Newsstand Kit 只有3个类:NKLibrary,NKIssue和 ...

  7. Oracle中SQL语句转化IP地址到数字

    CREATE OR REPLACE FUNCTION ip_num(ipaddress IN VARCHAR2) RETURN NUMBER AS ipnum ; pos1 ; pos2 ; BEGI ...

  8. PostGIS安装

    PostGIS安装 1.软件下载 postgresql-9.6.1-1-windows-x64-binaries.zip https://www.postgresql.org/download/win ...

  9. ArcGIS基于DEM计算水流方向的方法(D8算法)

    ArcGIS采用D8算法计算水流方向(9.3.1后新增),输入数据应首先完成了洼地填充处理: One of the keys to deriving hydrologic characteristic ...

  10. 安卓测试【三】adb简单命令及monkey使用

    Ⅰ 配置好android sdk环境变量之后,将android手机连接到电脑上,进行一些adb的简单命令的操作. adb,安卓调试桥,android   sdk的一个工具.直接操作管理安卓模拟器或者真 ...