java事务(二)——本地事务
本地事务
事务类型
事务可以分为本地事务和分布式事务两种类型。这两种事务类型是根据访问并更新的数据资源的多少来进行区分的。本地事务是在单个数据源上进行数据的访问和更新,而分布式事务是跨越多个数据源来进行数据的访问和更新。在这里要说的事务是基于数据库这种数据源的。
JDBC事务
在JAVA中,我们使用JDBC来连接数据库,访问和更新数据。那么在JDBC中是如何实现事务的,事务是被谁来管理的?这个答案当然是数据库,JDBC本身并没有处理事务的能力,而是依赖于底层数据库,底层数据库来提供事务的服务。在很多资料上会提到,JDBC的事务是基于连接的,也就是那个Connection对象,这个连接的本质其实是连接到数据库的一个Socket,与数据库建立连接以后就可以向数据库发送指令和数据,最终数据库会根据接收到的指令和数据来进行增删改查以及事务的处理。另外,事务是被限制在单个连接上的,这就好像我们去银行的营业厅办理业务,营业厅有多个窗口,我们只会在自己的窗口上与银行工作人员进行沟通并处理自身的业务,而不能跨窗口,告诉别的窗口的工作人员把那哥们的钱转到自己卡上,这事也就只能想想。
数据库事务例子
下面先看一个MYSQL数据库事务的例子:
1、创建表
创建用户表
CREATE TABLE USERS
(
USER_ID INT NOT NULL AUTO_INCREMENT COMMENT '自增主键',
USER_NAME VARCHAR(25) NOT NULL COMMENT '用户名',
PASSWORD VARCHAR(25) NOT NULL COMMENT '密码',
GENDER VARCHAR(1) COMMENT '性别',
PHONE_NO VARCHAR(11) NOT NULL COMMENT '手机号',
CREATE_TIME DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP() COMMENT '创建时间',
PRIMARY KEY (USER_ID)
)
COMMENT = '用户表';
创建用户和角色的关联关系表
CREATE TABLE USER_ROLE_RELATION
(
REL_ID INT NOT NULL AUTO_INCREMENT COMMENT '自增主键',
USER_ID INT NOT NULL COMMENT '用户ID',
ROLE_ID INT NOT NULL COMMENT '角色ID',
PRIMARY KEY (REL_ID)
)
COMMENT = '用户和角色对应关系表'
2、创建存储过程,在存储过程中使用事务
BEGIN
#声明一个标志位,默认为0
DECLARE T_ERROR INTEGER DEFAULT 0;
#如果事务执行过程中出现异常,那么把标志位设置为1
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET T_ERROR = 1;
#开始事务
START TRANSACTION;
INSERT INTO USERS (USER_NAME, PASSWORD, GENDER, PHONE_NO) VALUES ('zhangsan', '', '男', '');
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES ('', '');
#如果执行成功,直接提交,否则回滚
IF T_ERROR = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END
3、执行存储过程
存储过程执行成功以后,数据库的这两个表中会分别出现一条记录。然后把
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES ('', '');
这个语句改为:
#这条INSERT语句违反了非空约束,会抛出异常
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES (NULL, '');
重新保存并执行存储过程,结果是两个表中都没有新增记录。两条SQL语句要么同时成功,要么同时失败。
JDBC事务例子
JDBC中如果需要手动提交事务的话,需要用到Connection对象中的三个方法:
//设置是否自动提交
setAutoCommit()
//提交
commit()
//回滚
rollback()
在JDBC中事务的提交方式默认是自动提交的,手动提交的事务的话需要更改默认设置:
Connection.setAutoCommit(false)
下面这个例子是假设新增一个用户并给用户赋默认权限,那么需要同时向两张表中分别插入一条记录,把新增用户和赋权限看做是一个执行单元,放在一个事务中。
package person.lb.jdbc; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class TestJDBCTransAction { static {
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
//执行事务
executeTransaction();
} private static void executeTransaction() {
Connection conn = null;
Statement st1 = null;
Statement st2 = null;
ResultSet rs = null;
try {
//获取数据库连接
conn = (Connection) DriverManager.getConnection(
"jdbc:mysql://192.168.0.105:3306/TEST",
"root",
"root");
conn.setAutoCommit(false); st1 = (Statement) conn.createStatement();
st2 = (Statement) conn.createStatement();
//插入用户信息
st1.execute("INSERT INTO USERS (USER_NAME, PASSWORD, GENDER, PHONE_NO) "
+ "VALUES ('zhangsan', '123456', '男', '11111111111')"
, Statement.RETURN_GENERATED_KEYS);
//获取增长列的新值
rs = st1.getGeneratedKeys();
String userID = "";
if(rs.next()) {
userID = rs.getString(1);
}
//插入用户和角色关联数据
st2.execute("INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES (" +userID +", '1')");
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if(rs != null) {
rs.close();
}
if(st1 != null) {
st1.close();
}
if(st2 != null) {
st2.close();
}
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
程序执行结果如下:
USERS表

USER_ROLE_RELATION表

到这里,JAVA的本地事务算是写完了。
java事务(二)——本地事务的更多相关文章
- Java中的事务——全局事务与本地事务
转载,原文来源 http://www.hollischuang.com Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务.这是从事务的实现角度区 ...
- 跟我学Spring3(9.1):Spring的事务之数据库事务概述
原文出处: 张开涛 9.1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致 ...
- Java开发学习(二十二)----Spring事务属性、事务传播行为
一.事务配置 上面这些属性都可以在@Transactional注解的参数上进行设置. readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true. timeout ...
- Java开发学习(二十一)----Spring事务简介与事务角色解析
一.Spring事务简介 1.1 相关概念介绍 事务作用:在数据层保障一系列的数据库操作同成功同失败 Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败 数据层有事务我们可以理解 ...
- JAVA JDBC(存储过程和事务管理)
1.什么是存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程 ...
- 分布式事务二TCC
分布式事务解决方案之TCC 4.1.什么是TCC事务 TCC是Try.Confirm.Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try.确认Confirm.撤销Cancel ...
- RocketMQ入门到入土(二)事务消息&顺序消息
接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...
- JavaWeb学习总结(十二)--事务
一.事务的介绍 1.1 什么是事务 银行转账!张三转10000块到李四的账户,这其实需要两条SQL语句: 给张三的账户减去10000元: 给李四的账户加上10000元. 如果在第一条SQL语句执行成功 ...
- Java中的事务——JDBC事务和JTA事务
Java中的事务——JDBC事务和JTA事务 转载:http://www.hollischuang.com/archives/1658 之前的事务介绍基本都是数据库层面的事务,本文来介绍一下J2EE中 ...
随机推荐
- python-绘图matplotlib
<Python编程:从入门到实践>读书笔记 1.使用plot()绘制简单的折线图 import matplotlib.pyplot as plt va=[1,2,3,4,5] sq=[1, ...
- 转:探索C++0x: 1. 静态断言(static_assert)
转自:http://www.cppblog.com/thesys/articles/116985.html 简介 C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做 ...
- LeetCode:二叉搜索树中第K小的数【230】
LeetCode:二叉搜索树中第K小的数[230] 题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ...
- Python 优雅的操作字典
Python 中的字典是Python中一个键值映射的数据结构,下面介绍一下如何优雅的操作字典. 来源:https://www.linuxzen.com/python-you-ya-de-cao-zuo ...
- 14链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 快慢指针 快指针 先走k 步, 然后快慢指针一起走 当快指针走到null 时, 慢指针就是所求的倒数第k个节点 tips: 判断k是否 ...
- windo form 窗体布局方式
DataGridView:显示数据表后台数据绑定:List<xxx> list = new List<xxx>();dataGridView1.DataSource = lis ...
- 如何生成.a文件,小心有坑!!
.a文件是一种对实现文件细节进行隐藏的打包文件. 由于是打包文件,所以需要创建工程,将功能代码添加到工程.下面是创建.a文件的具体步骤: Step One:打开Xcode(此处使用的Xcode 8.2 ...
- clipbrd剪切板查看器
本文,我们来学习一下简单的概念,即,如何查看系统剪贴版里面有什么内容? 如果要想看.或者验证系统剪贴版里面都有什么内容,最为简单的方法就是通过"粘贴"的操作来验证! 但是, ...
- vim终端复制_不开启xterm_clipboard的解决方式
后来发现了另外的方法,比这个更好==> 完美解决vim在终端不能复制的问题 http://www.cnblogs.com/cheerupforyou/p/6958695.html 使用xsehl ...
- json-lib反序列化抽象属性及对象
使用json默认反序列化接口反序列化对象时,对象的类型必须的确定的,比如不能是抽象类型,否则会报无法实例化对象的异常 如有下列类定义: public abstract class AbstracObj ...