JDBC核心技术之(二)事物

6.jdbc事物

什么是事物:

事物就是逻辑上的一组操作,要么成功,要么失败!(比如转账 A 给 B 转账,A转出去了,B没收到,那么就不应该算成功,而是应该全部失败.)

事物的特性:

      • 原子性:意思是不可以分割
      • 一致性:意思就是事物从一个状态到另一个状态,应该是一致的,比如说转账(A有1000元,B有1000元,他们一共2000元;现在A转给B 500元,那么转账之后A 有500元,B 有1500元[中间不考虑手续费什么的..],这样他们还是
        2000元,就是前后一致的。)
      • 隔离性:意思一个事物一旦开启,就应该不受其他事物的影响(还是用转账来举例: A去ATM上查有1000元,在查的同时,B给A转了 500元,但是现在A 还没有退出当前事物,因此A 就不应该知道B 给他转了500元。)
      • 永久性: 意思就是一旦事物提交,就应该永久的存起来

如何开始事物?

一般来说,事物都是默认开启的,我们要自己来控制事物,一般涉及到如下步骤

      • 设置不默认开启事物
      • 提交事物
      • 事物错误,回滚

来看看代码


@Test

public void test_trans(){

try {

Class .forName( "com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection( url, user, password);

connection .setAutoCommit( false);//设置不默认开启事物

PreparedStatement ps = connection.prepareStatement( "update
test set name=‘000‘ where id=1");

ps .executeUpdate();

int i = 1 /0; //错误

ps = connection. prepareStatement("update
test set name=‘222‘ where id=2");

ps .executeUpdate();

connection .commit(); //事物提交

catch (Exception e) {

e .printStackTrace();

try {

connection.rollback ();//事物回滚

catch (SQLException e1) {

e1 .printStackTrace();

}

}finally {

//关闭资源

}

}

如果步骤比较多,然后不确定有一个步骤是否会有错,这时候可以设置回滚点

看下代码


@Test

public void test_trans1(){

Savepoint sp  = null;

try {

Class .forName( "com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection( url, user, password);

connection .setAutoCommit( false);//设置不默认开启事物

PreparedStatement ps = connection.prepareStatement( "update
test set name=‘000‘ where id=1");

ps .executeUpdate();

sp = connection. setSavepoint();//设置回滚点

int i = 1 /0; //错误

ps = connection. prepareStatement("update
test set name=‘222‘ where id=2");

ps .executeUpdate();

catch (Exception e) {

e .printStackTrace();

try {

connection.rollback (sp); //事物回滚

catch (SQLException e1) {

e1 .printStackTrace();

}

}finally {

try {

connection.commit ();

catch (SQLException e) {

e .printStackTrace();

}//事物提交

//关闭资源

}

}

我自己的建议是能不用回滚点就不用它。

事物的隔离级别

TRANSACTION_READ_UNCOMMITTED

指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。

TRANSACTION_READ_COMMITTED

指示不可以发生脏读的常量;不可重复读和虚读可以发生。

TRANSACTION_REPEATABLE_READ

指示不可以发生脏读和不可重复读的常量;虚读可以发生。

TRANSACTION_SERIALIZABLE

指示不可以发生脏读、不可重复读和虚读的常量。

java.sql.Connection
public static final int TRANSACTION_READ_COMMITTED 2
public static final int TRANSACTION_READ_UNCOMMITTED 1
public static final int TRANSACTION_REPEATABLE_READ 4
public static final int TRANSACTION_SERIALIZABLE 8

这几个隔离级别的脏读,不可重复读,幻读(虚读)到底是什么意思?

在事务管理中违反ACID特性的3个问题:脏读取、不可重复读和幻影行。如果存在多个并发的事务在运行,而这些事务操作了同一个数据来完成他们的任务,就会导致3个问题的存在。要解决它们,就必须在事务之间定义合适的隔离级别。事务之间存在的3个问题是:

脏读取 (Dirty read)

当一个事务读取了另一个事务尚未提交的更新,就叫脏读取。在另一个事务回滚的情况下,当前事务所读取的另一个事务的数据就是无效的。

不可重复读取(Nonrepeatable read)

在一个事务中执行多次同样的查询操作,但每次查询的结果都不一样,就叫做不可重复读取,通常这种情况是由于数据在二次查询之间被另一个并发的事务所修改。

幻读(Phantom rows)

这是对事务危害最小的一个问候,它类似不可重复读取,也是一个事务的更新结果影响到另一个事务问题。但是它不仅影响另一个事务查询结果,而且还会使查询语句返回一些不同的行录行。

这3个问题危害程度依次为:脏读取最大、不可重复读取其次、幻读最小。

如何查询数据库的默认事物级别:

mysql>

mysql>  select @@tx_isolation;

+-----------------+

| @@tx_isolation  |

+-----------------+

| REPEATABLE-READ |

+-----------------+

1 row in set (0.00 sec)

默认的是:指示不可以发生脏读和不可重复读的常量;虚读可以发生

一般这个级别基本上能够满足我们的需求了

下面我们来试试测试下:

先修改数据库的事物级别为最低的;

修改后的结果:

mysql> select @@tx_isolation;

+------------------+

| @@tx_isolation   |

+------------------+

| READ-UNCOMMITTED |

+------------------+

1 row in set (0.00 sec)

先看下数据库

同时两个事物再跑:

先测试脏读

这个时候一个事物(A)在查询,开始查询出来money=1000,然后另一个事物(B)修改价格,这时候事物(A)再次查询,就变成了money=1500,读取到了B还没有提交的数据叫脏读。

同时也出现了另一个错误,叫不可重复读,事物A前后读取的数据不一样。

还有一个幻读,这个不好测试,就在这里不测了

时间: 2024-10-09 20:10:32

JDBC核心技术之(二)事物的相关文章

java学习笔记 第二篇 核心技术(二)

第十四章 集合类 集合类用来存放对象的引用.继承关系如下图: 14.1 Collection 接口 是层次结构中的根接口,构成Collection的单位称为元素.Collection接口不能直接使用,但该接口提供了添加元素.删除元素.管理数据的方法. Collection接口常用方法: 14.2 List 集合 包括List接口以及List集合的所有实现类.List集合中的元素允许重复,各元素循序就是对象插入的顺序 1.List接口,两个重要方法: get(int index): 获取指定索引位

JDBC高级特性(二)分布式事和JTA基本原理

在进入主题之前我们首先来了解一下JNDI和连接池~ 一.JNDI 1)是一组在Java应用中访问命名和目录服务的API(Java命名与目录接口) 命名服务将名称和对象联系起来,使得我们可以通过名称访问对象. 目录服务是命名服务的扩展,两者之间的关键差别是目录服务中对象可以有属性(例如:用户有email地址),而命名服务中对象没有属性. 2)JNDI API提供了一种统一的方式,可以在本地或网络上查找和访问服务 各种服务在命名服务器上注册一个名称,需要使用服务的应用程序通过JNDI找到对应服务就可

JDBC高级特性(二)事务、并发控制和行集

一.事务 事务是指一个工作单元,它包括了一组加入,删除,改动等数据操作命令,这组命令作为一个总体向系统提交运行,要么都运行成功,要么所有恢复 在JDBC中使用事务 1)con.setAutoCommit(false),取消自己主动提交 2)对数据库运行一个或多个操作(一个或多个SQL语句) 3)con.commit().提交事务(上面的第二部的多个操作就作为一个总体提交运行) 4)假设某个操作失败.通过con.rollback()回滚全部操作(撤销以上的操作,将数据恢复为运行前状态) 事务处理依

JDBC学习笔记二

Statement执行更新操作 Statement:Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.Statement对象,用于执行不带参数的简单SQL语句. 通过JDBC向指定的数据表中插入一条记录,需要注意下面的几点: * 1.Statement:用于执行SQL语句的对象 * 1).通过COnnection的createStatement()方法来获取 * 2).通过excuteUpdate(sql)可以执行S

JDBC详解(二)

一:Statement与PreparedStatement的注意点 存在sql注入的危险,如果用户传入的id为"2 or 1=1",将删除表中的所有数据.而PreparedStatement有效的防止sql注入(SQl语句在程序运行前已经进行了预编译,当运行时动态的把参数传给PreparedStatement时,及时参数里有敏感字符如:"or 1=1",数据库也会作为一个字段的属性值来处理而不会作为一个SQL指令): 二:批处理(Batch) 对于大量的批处理,建议

Java核心技术(二) —— Java的基本程序设计结构

本文主要讲述程序设计相关的基本概念在Java中的实现方式,涉及的内容很多很细,包括注释.数据类型.变量.运算符.字符串.输入输出.控制流.大数值和数组. 1.基本认知 (1)Java对大小写敏感 (2)源代码的文件名必须与公共类的名字相同,并以.java作为扩展名 (3)源代码文件经过编译得到一个包含这个类的字节码的文件,并将其自动地命名为同名文件,只不过扩展名为.class,并与源文件存储在同一个目录下. (4)运行编译后的程序时,java虚拟机将从制定类中的main方法(方法即函数)开始执行

jdbc核心技术三--存储过程

存储过程是什么? 存储过程是一段代码,存储在数据库中,可以被程序调用 创建一个存储过程 create PROCEDURE SELECT_TESTTWO (IN TESTID LONG ,INOUT TESTALL VARCHAR(255)) BEGIN SELECT `name` from test where id = TESTID INTO TESTALL; END 创建存储过程指令:create PROCEDURE PROCEDURE_Name(输入,输出参数,可以有多个) 结构体 BEG

Spring核心技术(二)——Spring的依赖及其注入

本文将继续前文,描述Spring IoC中的依赖处理. 依赖 一般情况下企业应用不会只有一个对象(或者是Spring Bean).甚至最简单的应用都要多个对象来协同工作来让终端用户看到一个完整的应用的.下一部分将解释开发者如何从仅仅定义单独的Bean,到让这些Bean在一个应用中协同工作. 依赖注入 依赖注入是一个让对象只通过构造参数,工厂方法的参数或者配置的属性来定义他们的依赖的过程.这些依赖也是对象所需要协同工作的对象.容器会在创建Bean的时候注入这些依赖.整个过程完全反转了由Bean自己

复习课程jdbc:使用配置文件properties进行连接数据库,数据库存取图片,批处理,时间戳,事物回滚等等

使用配置文件properties进行连接数据库 首先创建一个file自定义文件名,但是后缀名必须改为.properties(不分大小写):如config.properties: 然后双击config.properties进行编辑:此文件数据是根据键值对来存储的:我们可以把连接数据库的一些连接字符串存储在此文件里:然后用的时候直接读配置文件,到时候更换的时候方便移植和修改. name