Java大数据之路--事务

事务


事务概述

在一个事件中,有许多单元组成,这些单元要么全部成功,或者全部失败,这些单元全部组成起来称之为一个事务。

  • 案例

比如简单的转账业务,sql实现

开启事务
start transaction;
update account set money = money-100 where name ='小明';
update account set money = money+100 where name ='小红';
commit; 或者 rollback;

由于这个事件需要同时发生或者同时不发生,所以需要把这两句sql写在一个事务中。不开启事务,mysql默认一条语句为一个事务。

  • JDBC事务案例

在JDBC中也是一条语句为一个事务,如果需要多条sql语句在同一个事务中,就需要开启事务。

conn.setAutoCommit(boolean)

开启事务。默认值位true。代表开启自动提交,一句sql就是一个事务。修改为false,代表关闭自动提交,意味着开启使用,多个sql可以在同一个事务中执行。

conn.commit()提交事务
conn.rollback()回滚事务
conn.rollback(Savepoint sp)回滚到记录点

 

  • JDBC代码实现
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//事务测试
public class TransDemo1 {

	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
        SavePoint sp = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day16", "root", "root");
			//开启事务
			conn.setAutoCommit(false);//默认值为true,代表会自动提交。
			//自动提交意味着一句sql就是一个事务,执行sql就会立刻提交这个事务,修改数据库中的数据。
			//设置为false,代表不会自动提交,表示开启事务,需要手动提交或回滚。
			ps = conn.prepareStatement("update user set money = money -100 where name=?");
			ps.setString(1, "a");
			ps.executeUpdate();
            //设置事务回滚点
            //sp = conn.setSavePoint();
			int i =1/0;
			ps = conn.prepareStatement("update user set money = money +100 where name = ?");
			ps.setString(1, "b");
			ps.executeUpdate();
			conn.commit();//在sql书写完成之后,选择使用commit方法提交事务。
		} catch (Exception e) {
			if(conn !=null){
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				} }
			e.printStackTrace();
		}finally{
			if(conn !=null){
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
					conn = null;
				} }
			if(rs !=null){
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
					rs = null;
				} }
			if(ps !=null){
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
					ps =null;
				} } } } }

事务特性

  • 事务四大特性(ACID)

原子性(Atomicity):一个事务中多个单元,是不能分割的,要么同时成功,要么同时失败。

一致性(Consistency):事务修改数据前后,数据库的数据的完整性,仍然保持一致。

隔离性(Isolation):数据库中一个事务,可能被其他事务影响,为了避免这种情况发生,数据库提供了几种隔离级别供用户选择。

持久性(Durability):数据库中的事务一旦提交,就会永久改变,无法改变,即使数据库损坏,也无法恢复原有的数据。

  • 数据库中的四大特性

数据库中除了隔离性,另外三种性质都得到了具体实现,开发中直接使用即可,唯独隔离性,没有做出具体实现。原因是:

每一个数据库用户,对于数据库的隔离级别看法不同,数据库不能写死其隔离级别,如果写死的话会很不友好,所以隔离性需要用户自行设置。

考虑数据库的隔离级别,就是分析数据库中事务之间的线程安全问题,所以可以从数据涉及读和写来分析。

两个事务同时读取数据:

这种情况不会存在线程安全问题。因为两个事务对应的线程都未对数据进行修改,任何人读取的数据内容都相同。

两个事务同时写入数据:

这种情况一定会存在线程安全问题。因为两个事务对应的线程都会对数据进行修改,第二次修改可能会覆盖第一次的操作,所以应该将两个事务严格分开。可以通过修改数据库的隔离级别,来保证两个事务分别执行,避免出现线程安全问题。

一个事务写,一个事务读:

在面对一个事务写,一个事务读这种情况时,可以选择修改数据库的隔离级别达到自己想要的效果。如果要求数据库安全性与正确性,则可以选择最高的隔离级别。如果要求数据的写入速度,则可以选择数据库的最低隔离级别。多数情况需要两者兼顾,可以选择中间两个隔离级别。面对数据库中存储的脏读,不可重复读,虚读/幻读这些情况,也可以根据自己的需求,修改数据库的隔离级别。防止这些问题的隔离级别,推荐使用repeatable read。原因是这个级别,不会出现脏读,和不可重复读。而虚读出现的情况极少。可以认为当前隔离级别是安全且能够保证执行效率的。

  • 几种事务之间互相影响的情景分析

脏读:一个事务读取到另一个未提交事务的数据,导致数据前后读取不一致。

a:1000 买家
b:1000 商家
--------------------------------------------------------------------
a:start transaction;
update user set money = money -100 where name='a';
update user set money =money +100 where name ='b';
-----------------------------------------------------------------------------
b:start transaction;
select * from user where name ='b';-----1100
-----------------------------------------------
a:rollback;
-------------------------------------------------------
b:select * from user where name ='b';-----1000

不可重复读:一个事务读取到另一个已经提交事务的数据,在事务提交前后,读取的数据内容不一致,这种现象就称之为不可重复读。

------------------------------------------------------------------------
a:1000 1000 1000
------------------------------------------------------------------------
b:start transaction;
select hq from account where name='a';----1000;
select dq from account where name='a';----1000;
select gp from account where name='a';----1000;
-----------------------------------------------------------------
a:start transaction;
update account set hq = hq-100 where name='a';
commit;
------------------------------------------------------------------
b:
select hq+dq+gq from account where name='a';---2900
--------------------------------------------------------------------
hq 1000
dq 1000 
gp 1000
sum 2900

虚读/幻读:在整表操作中,一个事务读取到另外一个已经提交事务的数据,导致事务提交前后数据不一致的现象,这种现象称之为虚读/幻读。

-----------------------------------------------------------------------------
a:1000
b:2000
------------------------------------------------------------------------------
d:
start transaction;
select sum(money) from user; ----3000
select count(money) from user; ----2
---------------------------------------------------------------------
c: 3000
start transaction;
insert into user values('c',3000);
commit;
----------------------------------------------------------------------
d:
select avg(money) from user;---- 1500

数据库隔离级别

在数据库的事务特性当中,唯独没有实现隔离性的内容,转而是为用户提供四个隔离界别的选项,用户可以根据自己的需求,选择合适隔离级别。

  • 四个隔离级别

read uncommitted;

脏读,不可重复读,虚读/幻读,都会出现。数据库安全性最低,但是效率最高。
read committed;可以防止脏读。不可以防止不可重复读及虚读/幻读。数据库安全性较低,效率较高。
repeatable read;

可以防止脏读,和不可重复读。不可以方式虚读/幻读.数据库的安全性较高,效率较低。mysql默认的隔离级别。

serializable;

可以防止脏读,不可重复度和虚读/幻读.它是mysql最高的隔离级别。是一个串行化的处理方式,虽然安全性较高,但是执行效率过低。

  • 隔离级别的选择

安全serializable > repeatable read >read committed>read uncommitted

性能read uncommitted>read committed> repeatable read>serializable由于read uncommitted隔离级别过低,安全性保证较差,所以实际开发中使用较少。serializable隔离级别过高,安全性虽然较高,但是效率极低,对于开发影响较大,所以实际开发中很少使用。

read committedrepeatable read两个隔离级别较为使用,对于数据安全性和语句执行效率都有较好的保证,开始时多数会采用两者其中一个。

修改数据库的事务级别
set global/session transaction isolation level read uncommitted;
set transaction isolation level read uncommitted;临时修改,只对下一次的事务生效

-------------------------------------------------------------------------------------------

查询当前数据库的隔离级别
select @@tx_isoaltion;

数据库中的锁

  • 共享锁和排他锁

​​​​​​​a. 在非serializable隔离级别之下,查询不加锁。增删改添加排它锁。

b. serializable隔离级别之下,查询添加共享锁。增删改添加排它锁。

特点:

i. 共享锁和共享锁可以共存。

ii. 共享锁和排它锁不能共存。

iii. 排它锁和排它锁不能共存。

  • 表级锁和行级锁

​​​​​​​表级锁:添加锁之后,当前表格,不允许另外的事务操作。

行级锁:添加锁之后,当前表格中的某一行或几行,不允许另外的事务操作。

  • 死锁​​​​​​​

两个线程相互等待对方释放资源,这种现象称之为死锁。

解决死锁的方案:

i. 销毁其中任意一个线程。

ii. 修改代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值