更新:2019/3/29

目录

简介

事务的四个特性

一个小Demo

目录结构

jdbc.properties

JDBCUtil.java

TestTransaction.java【核心代码】

数据库

demo2


简介

事务(Transaction) 其实指的一组操作,里面包含许多个单一的逻辑。只要有一个逻辑没有执行成功,那么都算失败。 所有的数据都回归到最初的状态(回滚)

简单的说:银行要把张三的钱转到李四的账户上。张三扣钱,李四加钱。这两个操作要都成功才算转账成功,不能张三扣完钱,李四没收到。事务就是解决这样的问题。

事务的四个特性

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

一个小Demo

目录结构

记得导入my-connector jar包和JUnt 5

jdbc.properties

连接数据库的配置文件

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost/bank?useSSL=false&serverTimezone=UTC
name=root
password=123456

要操作的是bank数据库 ,url是mysql8的写法,不然会报错

JDBCUtil.java

工具类,直接用

package com.zhujunwei.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; public class JDBCUtil { static String driverClass = null;
static String url = null;
static String name = null;
static String password= null; static{
try {
//1. 创建一个属性配置对象
Properties properties = new Properties();
// InputStream is = new FileInputStream("jdbc.properties"); //使用类加载器,去读取src底下的资源文件。 后面在servlet
InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
//导入输入流。
properties.load(is); //读取属性
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
name = properties.getProperty("name");
password = properties.getProperty("password"); } catch (Exception e) {
e.printStackTrace();
}
} /**
* 获取连接对象
* @return
*/
public static Connection getConn(){
Connection conn = null;
try {
Class.forName(driverClass);
//静态代码块 ---> 类加载了,就执行。 java.sql.DriverManager.registerDriver(new Driver());
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
//2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
conn = DriverManager.getConnection(url, name, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
} /**
* 释放资源
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn , Statement st , ResultSet rs){
closeRs(rs);
closeSt(st);
closeConn(conn);
}
public static void release(Connection conn , Statement st){
closeSt(st);
closeConn(conn);
} private static void closeRs(ResultSet rs){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
} private static void closeSt(Statement st){
try {
if(st != null){
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
} private static void closeConn(Connection conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}

TestTransaction.java【核心代码】

package com.zhujunwei;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; import org.junit.Test; import com.zhujunwei.utils.JDBCUtil; public class TestTransaction {
@Test
public void test() { Connection conn = null ;
PreparedStatement ps = null ;
System.out.println("-----");
try {
conn = JDBCUtil.getConn();
//1.关闭自动提交
conn.setAutoCommit(false);
String sql = "update account set money = money- ? where id = ?";
ps = conn.prepareStatement(sql); //减钱
ps.setInt(1, 100);
ps.setInt(2,1);
int len = ps.executeUpdate();
System.out.println("成功修改"+len+"行。"); //手工加的异常,程序要想正常运行请注释
int a = 10/0; //加钱
ps.setInt(1, -100);
ps.setInt(2,2);
len = ps.executeUpdate();
System.out.println("成功修改"+len+"行。"); //2.提交数据
conn.commit();
} catch (SQLException e) {
//3.异常就回滚
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps);
}
}
}

数据库

  1. 运行一波,在test()方法上鼠标右键,Run as >Junit Test

2. 你会发现程序出现错了,但是扣款是成功的,你回到数据库看一下,发现并没有变,这是因为回滚了。

把int a = 10/0;注释掉再运行一下。

3.运行是成功的,回到数据库看一下,发现数据库改变了。

demo2

以前的老例子了,不看也罢。

package com.zjw.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; /**
*
* @描述:事务:转账
* @作者: zjw
* @时间: 2018年7月19日 上午11:06:43
*/
public class TranferMain
{
public static void main(String[] args)
{
String fromName = "张三1" ;
String toName = "李四2" ;
double money = 1 ; tranfer(fromName,toName,money);
} private static void tranfer(String fromName, String toName, double money)
{
Connection connection = null ;
PreparedStatement ps = null ;
try
{
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myfirst?useSSL=false&serverTimezone=UTC";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url, user, password);
/* 一个链接里面的所有sql语句要么都成功,要么都失败
*
* 自动提交
* */
boolean flag = connection.getAutoCommit();
/* 不让自动提交
* mysql等数据库是自动提交的,
* 但是oracle:需要手动提交
* */
connection.setAutoCommit(false); String sql = "update student set balance = balance-? where name = ?";
ps = connection.prepareStatement(sql);
ps.setObject(1, money);
ps.setObject(2, fromName);
int res = ps.executeUpdate();
if(res>0)
{
System.out.println(fromName+"扣钱成功"+"扣钱:"+money);
ps.close();
sql = "update student set balance = balance+? where name = ?";
ps = connection.prepareStatement(sql);
ps.setObject(1, money);
ps.setObject(2, toName);
res = ps.executeUpdate();
if(res>0)
{
System.out.println(toName+"收钱成功"+"收钱:"+money);
//提交事务
connection.commit();
//还原现场
connection.setAutoCommit(flag);
} } } catch (Exception e)
{
e.printStackTrace();
//回滚
if (connection != null)
{
try
{
connection.rollback();
} catch (SQLException e1)
{
e1.printStackTrace();
}
}
} finally
{
try
{
ps.close();
ps = null ;
} catch (SQLException e)
{
e.printStackTrace();
}
try
{
connection.close();
connection = null ;
} catch (SQLException e)
{
e.printStackTrace();
}
}
} }

Java--事务,操作数据库,实现转账的更多相关文章

  1. JavaEE Day05 JDBC(用Java语言操作数据库)

    今日内容 基本概念 快速入门 对JDBC中各个接口和类的详解 一.基本概念 1.概念:Java Database Connectivity:Java数据库连接,Java语言操作数据库 2.本质:官方( ...

  2. JavaWeb_(Spring框架)整合Mybatis加入事务操作数据库

    整合Mybatis a)导包: i.Spring:基本包.aop.aspects.jdbc.tx.test: ii.Mybatis:mybatis-3.4.6 iii.整合包:mybatis-spri ...

  3. Java程序操作数据库SQLserver详解

    数据库基本操作:增删改查(CRUD) crud介绍(增.删.改.查操作) CRUD是指在做计算处理时的增加(Create).查询(Retrieve)(重新得到数据).更新(Update)和删除(Del ...

  4. Java DbUtils 操作数据库

    示例 1.新建项目,把数据库驱动.DbUtils的jar包添加到项目中 2.新建文件夹resource,标识为资源根目录,下面新建数据库连接的配置文件mysql.properties driver=c ...

  5. java jdbc操作数据库通用代码

    1.准备工作 1> 新建一个配置文件,名为jdbc.properties将其放入src中 2>在项目中导入jdbc驱动,注意连接不同的数据库,所用到的驱动是不一样的,这些在网上都能找到 具 ...

  6. java连接操作数据库

    Connection 类prepareStatement(String sql) 创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库. PreparedState ...

  7. iOS sqlite 使用事务操作数据库

    业务层代码: //将解析的更新人员数据批量同步到数据库 +(void)operateCompUsers:(NSMutableArray*)operateCompUsers { sqliteHelper ...

  8. Java jdbc 操作数据库详解

    原文地址https://www.cnblogs.com/huguodong/p/5910859.html JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  9. 07_数据库创建,添加c3p0操作所需的jar包,编写c3p0-config.xml文件,编写User.java,编写jdbcUtils.java实现操作数据库的模板工具类,UserDao编写,Dao

     1  创建day14数据库,创建user.sql表: A 创建数据库 day14 B 创建数据表 users create table users ( id int primary keyaut ...

  10. Java Web的数据库操作(一)

    一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库交互,JDBC在Java程序与 ...

随机推荐

  1. java中反射-字节码和类加载器

    多态的一个表现 子类类型赋值给父类 Father f1 = New Son() 调用子类方法报错. 调用父类方法OK.这个就是多态 一个对象能用什么方法,并不是取决于 它有什么方法. 而是取决于引用变 ...

  2. 【忍者算法】从公路跑步到链表成环:探索环形链表检测|LeetCode第141题 环形链表

    从公路跑步到链表成环:探索环形链表检测 生活中的环形 想象两个人在环形跑道上跑步,一个跑得快,一个跑得慢.如果他们一直跑下去,快的跑者一定会从后面追上慢的跑者.这就是我们今天要讨论的环形链表问题的现实 ...

  3. linux的使用(2)

    1,覆盖 > cat 文件名a>文件名b:将文档a覆盖文档b 2,追加 >> cat 文档名a>>文档名b:将文档a追加到文档b后 追加错误 上图所示:尽量使用字母 ...

  4. autMan奥特曼机器人-安装或更新golang依赖

    autMan2.3.4及以上需要更新中间件或安装golang依赖,参照下列步骤: 一.直装版本 ssh下进入autMan文件夹下plugin/scripts下面输入以下指令: go get -u gi ...

  5. Flink - [02] 安装部署(Standalone)

    一.准备 1.角色规划 Flink Standalone 角色规划 节点名称 node01 node02 node03 master ○     worker   ○ ○ zookeeper ○ ○ ...

  6. win - [01] 修改网络连接名称(网络1、网络2...网络10)

    修改网络连接的名称 1.打开运行窗口:Windows 键 + R 2.在运行窗口输入 regedit,打开注册表编辑器 3.在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsof ...

  7. C/C++跨平台开发1-windows和linux中的类库

    基本概念: 什么是库: 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 静态库:在程序链接的时候使用,链接器会将程序中使 ...

  8. 第二届獬豸杯wp

    第二届獬豸杯wp 容器密码:}2N|n_yxdt!G/Ru}|_zdn$@?6@CD8E 计算机和手机部分已经在第二届 獬豸杯-复现 - 萧瑟迪亲传大弟子 - 博客园这里发过了,服务器部分自己又写了一 ...

  9. 一次h5活动页面的踩坑 过程

    托好奇心的福,这几天又接了一个bug,哦不,一个非常锻炼个人能力的h5页面,期间涉及到很多问题,在此打算先占个坑,等日后有时间再慢慢记录,无论是swiper插件的使用,还是关于硬件加速的运用,又或者是 ...

  10. MySQL 常用优化

    目录 单表优化 字段 索引 查询SQL 引擎 MyISAM InnoDB 系统调优参数 升级硬件 读写分离 缓存 表分区 分区的好处是: 分区的限制和缺点: 分区的类型: 分区适合的场景有: 垂直拆分 ...