本地事务
事务类型
事务可以分为本地事务和分布式事务两种类型。这两种事务类型是根据访问并更新的数据资源的多少来进行区分的。本地事务是在单个数据源上进行数据的访问和更新,而分布式事务是跨越多个数据源来进行数据的访问和更新。在这里要说的事务是基于数据库这种数据源的。
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', '123456', '男', '11111111111');
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES ('333', '1');
#如果执行成功,直接提交,否则回滚
IF T_ERROR = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END
3、执行存储过程
存储过程执行成功以后,数据库的这两个表中会分别出现一条记录。然后把
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES ('333', '1');
这个语句改为:
#这条INSERT语句违反了非空约束,会抛出异常
INSERT INTO USER_ROLE_RELATION (USER_ID, ROLE_ID) VALUES (NULL, '1');
重新保存并执行存储过程,结果是两个表中都没有新增记录。两条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事务API(JTA)规范
一.引子 既然出现了分布式场景(DTP模型), 大java也及时制定出一套规范来给各大应用服务器.数据库/mq等厂商使用,以方便管理互通--->JTA闪亮登场.JTA(Java Transact ...
-
深入Java事务的原理与应用
一.什么是JAVA事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 ( ...
-
java事务管理
一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...
-
java事务 深入Java事务的原理与应用
一.什么是JAVA事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (iso ...
-
java事务(三)
java事务(三)——自己实现分布式事务 在上一篇<java事务(二)——本地事务>中已经提到了事务的类型,并对本地事务做了说明.而分布式事务是跨越多个数据源来对数据来进行访问和更新,在J ...
-
java事务(三)——自己实现分布式事务
在上一篇<java事务(二)——本地事务>中已经提到了事务的类型,并对本地事务做了说明.而分布式事务是跨越多个数据源来对数据来进行访问和更新,在JAVA中是使用JTA(Java Trans ...
-
温故而知新java事务
一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (iso ...
-
Java事务的原理与应用
Java事务的原理与应用 一.什么是Java事务 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (isolation ...
-
Java事务与JTA
一.什么是JAVA事务 通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令.更简答的说就是:要么 ...
-
转!!java事务的处理
java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前 ...
随机推荐
-
图——拓扑排序(uva10305)
John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...
-
使div下的图片自适应div的大小
div img{ max-width:100%; height:auto; } 这里div 要给固定的宽度 开始这里还想了半天 用网上的方法也不行 问老大 又一句话就给我解决了...老大真男神啊!!! ...
-
oc 关键字
assign适用于基本数据类型,weak是适用于NSObject对象,并且是一个弱引用. assign其实页可以用来修饰对象,那么为什么不用它呢?因为被assign修饰的对象在释放之后,指针的地址还是 ...
-
Unity3D ShaderLab Use Properties
在上一篇,学会了怎么使用ShaderLab 语法:Properties,这一次,我们将会使用属性值点亮材质球. 1:Delete>sampler2D _MainTex; 2:1行位置Add> ...
-
这是第二道题内容要求写一个银行的ATM系统 这个浪费了好长时间 ,遇到了许多问题,不过都解决了,上程序
下面的4个用户是我宿舍的,当然我是钱最多的,呵呵! #include<iostream>#include<string>using namespace std; class c ...
-
atcoder 它February 29th
Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB Problem Charlie was born January 1st ...
-
iOS生成一个32位的UUID
- (NSString *)uuidString { CFUUIDRef uuid_ref = CFUUIDCreate(NULL); CFStringRef uuid_string_ref= CFU ...
-
React 记录(7)
React文档:https://www.reactjscn.com/docs/handling-events.html 慢慢学习:对照教程文档,逐句猜解,截图 React官网:https://reac ...
-
SQL中 根据行号设置每行数据的排序数值
根据行号自动把当前行号插入到某列中 实现排序 update tempTable set DisplayOrder = right( CAST(rownum as NVARCHAR),5) from( ...
-
老古董---ASP.NET中aspx页面runat=";server";
自从 mvc3 被广泛的推进生产环境后,这个runat="server" 慢慢被人遗忘了... asp.net 的 webForm 基于控件的 html 渲染过程是否还记得呢?是 ...