JDBC处理事务
一、什么是事务?
在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
二、事务是必须满足4个条件(ACID)
- 事务的原子性( Atomicity):一组事务,要么成功;要么撤回。
- 一致性 (Consistency):事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务执行成功否,参与转账的两个账号余额之和应该是不变的。
- 隔离性(Isolation):事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
- 持久性(Durability):软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit 选项 决定什么时候吧事务保存到日志里。
三、MySQL中的事务
在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。
- 开启事务:start transaction
- 结束事务:commit或rollback
在执行SQL语句之前,先执行start transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所作出的影响会持久到数据库中,或者rollback,表示回滚到事务的起点,之前做的所有操作都被撤销了。
1 mysql> SELECT * FROM account;
2 +----+------+---------+
3 | id | NAME | balance |
4 +----+------+---------+
5 | 1 | zs | 1000.00 |
6 | 2 | ls | 1000.00 |
7 | 3 | ww | 1000.00 |
8 +----+------+---------+
9 3 rows in set (0.00 sec)
10
11 mysql> START TRANSACTION;
12 Query OK, 0 rows affected (0.00 sec)
13
14 mysql> UPDATE account SET balance=900 WHERE name = 'zs';
15 Query OK, 1 row affected (0.00 sec)
16 Rows matched: 1 Changed: 1 Warnings: 0
17
18 mysql> SELECT * FROM account;
19 +----+------+---------+
20 | id | NAME | balance |
21 +----+------+---------+
22 | 1 | zs | 900.00 |
23 | 2 | ls | 1000.00 |
24 | 3 | ww | 1000.00 |
25 +----+------+---------+
26 3 rows in set (0.00 sec)
27
28 mysql> UPDATE account SET balance=1100 WHERE name = 'ls';
29 Query OK, 1 row affected (0.00 sec)
30 Rows matched: 1 Changed: 1 Warnings: 0
31
32 mysql> SELECT * FROM account;
33 +----+------+---------+
34 | id | NAME | balance |
35 +----+------+---------+
36 | 1 | zs | 900.00 |
37 | 2 | ls | 1100.00 |
38 | 3 | ww | 1000.00 |
39 +----+------+---------+
40 3 rows in set (0.00 sec)
41
42 mysql> ROLLBACK;
43 Query OK, 0 rows affected (0.00 sec)
44
45 mysql> SELECT * FROM account;
46 +----+------+---------+
47 | id | NAME | balance |
48 +----+------+---------+
49 | 1 | zs | 1000.00 |
50 | 2 | ls | 1000.00 |
51 | 3 | ww | 1000.00 |
52 +----+------+---------+
53 3 rows in set (0.00 sec)
54
55 mysql> START TRANSACTION;
56 Query OK, 0 rows affected (0.00 sec)
57
58 mysql> UPDATE account SET balance=balance-100 WHERE name = 'zs';
59 Query OK, 1 row affected (0.00 sec)
60 Rows matched: 1 Changed: 1 Warnings: 0
61
62 mysql> SELECT * FROM account;
63 +----+------+---------+
64 | id | NAME | balance |
65 +----+------+---------+
66 | 1 | zs | 900.00 |
67 | 2 | ls | 1000.00 |
68 | 3 | ww | 1000.00 |
69 +----+------+---------+
70 3 rows in set (0.00 sec)
71
72 mysql> UPDATE account SET balance=balance+100 WHERE name = 'ls';
73 Query OK, 1 row affected (0.00 sec)
74 Rows matched: 1 Changed: 1 Warnings: 0
75
76 mysql> SELECT * FROM account;
77 +----+------+---------+
78 | id | NAME | balance |
79 +----+------+---------+
80 | 1 | zs | 900.00 |
81 | 2 | ls | 1100.00 |
82 | 3 | ww | 1000.00 |
83 +----+------+---------+
84 3 rows in set (0.00 sec)
85
86 mysql> commit;
87 Query OK, 0 rows affected (0.02 sec)
88
89 mysql> SELECT * FROM account;
90 +----+------+---------+
91 | id | NAME | balance |
92 +----+------+---------+
93 | 1 | zs | 900.00 |
94 | 2 | ls | 1100.00 |
95 | 3 | ww | 1000.00 |
96 +----+------+---------+
97 3 rows in set (0.00 sec)
四、JDBC事务
在JDBC中处理事务,都是通过Connection完成的。
同一事务中所有的操作,都在使用同一个Connection对象。
①JDBC中的事务
Connection的三个方法与事务有关:
- setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值为true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置为false,那么相当于开启了事务了;con.setAutoCommit(false) 表示开启事务。
- commit():提交结束事务。
- rollback():回滚结束事务。
JDBC处理事务的代码格式:
try{
con.setAutoCommit(false);//开启事务
......
con.commit();//try的最后提交事务
} catch() {
con.rollback();//回滚事务
}
示例:
1 public class AccountDao {
2 /*
3 * 修改指定用户的余额
4 * */
5 public void updateBalance(Connection con, String name,double balance) {
6 try {
7 String sql = "UPDATE account SET balance=balance+? WHERE name=?";
8 PreparedStatement pstmt = con.prepareStatement(sql);
9 pstmt.setDouble(1,balance);
10 pstmt.setString(2,name);
11 pstmt.executeUpdate();
12 }catch (Exception e) {
13 throw new RuntimeException(e);
14 }
15 }
16 }
1 import cn.itcast.jdbc.JdbcUtils;
2 import org.junit.Test;
3 import java.sql.Connection;
4 import java.sql.SQLException;
5
6 public class Demo1 {
7 /*
8 * 演示转账方法
9 * 所有对Connect的操作都在Service层进行的处理
10 * 把所有connection的操作隐藏起来,这需要使用自定义的小工具(day19_1)
11 * */
12 public void transferAccounts(String from,String to,double money) {
13 //对事务的操作
14 Connection con = null;
15 try{
16 con = JdbcUtils.getConnection();
17 con.setAutoCommit(false);
18 AccountDao dao = new AccountDao();
19 dao.updateBalance(con,from,-money);//给from减去相应金额
20 if (true){
21 throw new RuntimeException("不好意思,转账失败");
22 }
23 dao.updateBalance(con,to,+money);//给to加上相应金额
24 //提交事务
25 con.commit();
26
27 } catch (Exception e) {
28 try {
29 con.rollback();
30 } catch (SQLException e1) {
31 e.printStackTrace();
32 }
33 throw new RuntimeException(e);
34 }
35 }
36 @Test
37 public void fun1() {
38 transferAccounts("zs","ls",100);
39 }
40 }
五、事务隔离级别
1、事务的并发读问题
- 脏读:读取到另外一个事务未提交数据(不允许出来的事);
- 不可重复读:两次读取不一致;
- 幻读(虚读):读到另一事务已提交数据。
2、并发事务问题
因为并发事务导致的问题大致有5类,其中两类是更新问题三类是读问题。
- 脏读(dirty read):读到另一个事务的未提交新数据,即读取到了脏数据;
- 不可重复读(unrepeatable):对同一记录的两次读取不一致,因为另一事务对该记录做了修改;
- 幻读(虚读)(phantom read):对同一张表的两次查询不一致,因为另一事务插入了一条记录。
3、四大隔离级别
4个等级的事务隔离级别,在相同的数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。
1、SERIALIZABLE(串行化)
- 不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;
- 性能最差
2、REPEATABLE READ(可重复读)(MySQL)
- 防止脏读和不可重复读,不能处理幻读
- 性能比SERIALIZABLE好
3、READ COMMITTED(读已提交数据)(Oracle)
- 防止脏读,不能处理不可重复读和幻读;
- 性能比REPEATABLE READ好
4、READ UNCOMMITTED(读未提交数据)
- 可能出现任何事物并发问题,什么都不处理。
- 性能最好
六、MySQL隔离级别
MySQL的默认隔离级别为Repeatable read,可以通过下面语句查看:
SELECT @@`TX_ISOLATION`;
也可以通过下面语句来设置当前连接的隔离级别:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ ;//[4选1]
七、JDBC设置隔离级别
con.setTransactionIsolation(int level) :参数可选值如下:
- Connection.TRANSACTION_READ_UNCOMMITTED;
- Connection.TRANSACTION_READ_COMMITTED;
- Connection.TRANSACTION_REPEATABLE_READ;
- Connection.TRANSACTION_READ_SERIALIZABLE。
JDBC处理事务的更多相关文章
- Spring总结——AOP、JDBC和事务的总结
1.上一次总结了 Spring 的核心三大组件(Core,Beans,Context),今天总结的 AOP.JDBC和事务都可以看成是核心三大组件的应用. 其中 Spring 的事务管理又以 AOP ...
- 【JDBC】事务的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5868750.html 关于事务的理论知识.ACID特性等等,网上太多了,在此不一一重复.本文主要着重 事务 ...
- MySql事务及JDBC对事务的使用
一 .事务的几个重要特性 1. 原子性 事务内的每个内容不可分割,是一个统一的整体.或同时进行或同时消亡. 2.一致性 事务执行前和事务执行后,状态都是统一的.如A转B 100元,A和B数据总额度没有 ...
- JDBC 之 事务
1.概念:事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功. 2.数据库开启事务的命令dtl: Start transaction开启事务 Rollback回滚事务(撤销) ...
- JDBC之事务隔离级别以及ACID特性
JDBC之事务隔离级别以及ACID特性 事务隔离级别: 1.更新遗失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了.这是因为系统没有 ...
- 事务之使用JDBC进行事务的操作2
本篇将讲诉如何使用JDBC进行数据库有关事务的操作.在上一篇博客中已经介绍了事务的概念,和在MySQL命令行窗口进行开启事务,提交事务以及回滚事务的操作. 似乎事务和批处理都可以一次同时执行多条SQL ...
- JDBC控制事务
概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并 ...
- JDBC进行事务管理
JDBC进行事务管理 事务的四个特征:原子性 : 是指事务中包含的操作都被看做是一个逻辑单元一致性: 开始前和结束后数据库都处于一致性状态隔离性: 对数据库修改的多个事务是彼此隔离的持久性 事务完成之 ...
- Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...
1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback 回滚事务 •Commit ...
随机推荐
- mangodb的存储
mongodb基本命令 mongo #进入mongo命令行show dbs #查看所有数据库 use tutorial #切换到名为tutorial的数据库 show collections #查看数 ...
- P4382 [八省联考2018]劈配
题目链接 题意分析 受到了\(olinr\ \ julao\)的影响 写了匈牙利算法 首先 我们对于每一个人 从高到低枚举志愿 如果当前志愿的老师有剩余的话 那么我们就选 否则的话 我们看看谁的那个志 ...
- php解析word,获得文档中的图片
背景 前段时间在写一个功能:用原生php将获得word中的内容并导入到网站系统中.因为文档中存在公式,图片,表格等,因此写的比较麻烦. 思路 大体思路是先将word中格式为doc的文档转化为docx, ...
- 【转载】Analysis Service Tabular Model #002 Analysis services 的结构:一种产品 两个模型
Analysis Service 2012 Architecture – One Product, Two Models 在之前SQL Server 2008 R2 版本中的分析服务实际上只有一个版本 ...
- 18.async函数
1.含义 async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 Generator 函数,依次读取两个文件. var fs = require('fs'); var ...
- MYSQL中数据类型介绍
一.MySQL的数据类型 主要包括以下五大类: 主要包括以下五大类: 整数类型:bit. int . bit int . small int . tiny int . medium int .boo ...
- 用尾递归和普通递归实现n!算法,二者比较
尾递归 - Tail Recursion尾递归是针对传统的递归算法而言的, 传统的递归算法在很多时候被视为洪水猛兽. 它的名声狼籍, 好像永远和低效联系在一起.尾递归就是从最后开始计算, 每递归一次就 ...
- Visual Studio、.net framework、CLR与JDK、JRE、JVM、Eclipse
.net平台 java平台 开发工具 Visual Studio ...
- java爬虫爬取https协议的网站时,SSL报错, java.lang.IllegalArgumentException TSLv1.2 报错
目前在广州一家小公司实习,这里的学习环境还是挺好的,今天公司从业十几年的大佬让我检查一下几年前的爬虫程序是否还能使用…… 我从myeclipse上check out了大佬的程序,放到workspace ...
- python之virtualenv的简单使用
什么是virtualenv? virtualenv可以创建独立Python开发环境,比如当前的全局开发环境是python3.6,现在我们有一个项目需要使用django1.3,另一个项目需要使用djan ...