文档章节

Mysql事务详解

abinge2016
 abinge2016
发布于 2016/05/29 13:27
字数 1776
阅读 74
收藏 0

#事务 ##事务的概念

  • 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。

  • 例如:A——B转帐,对应于如下两条sql语句:

      update from account set money=money+100 where name='b';
      update from account set money=money-100 where name='a';
    
  • 数据库开启事务命令

      start transaction——>开启事务
      Rollback——>回滚事务
      Commit——>提交事务
    
      Start transaction
      ……
      commit
    

##使用事务

  • 当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列JDBC控制事务语句

      Connection.setAutoCommit(false); start transaction
      Connection.rollback();  rollback
      Connection.commit();  commit
    

##演示银行转帐案例

  • 在JDBC代码中使如下转帐操作在同一事务中执行:

      update from account set money=money-100 where name=‘a’;
      update from account set money=money+100 where name=‘b’;
    
  • 设置事务回滚点

      Savepoint sp = conn.setSavepoint();
      Conn.rollback(sp);//如果出现异常,则将从这个点开始回滚,而之前的操作不回滚
      Conn.commit();   //回滚后必须要提交
    

##事务的特性(ACID) ###原子性(Atomicity)

  • 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。  ###一致性(Consistency)
  • 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。 ###隔离性(Isolation)
  • 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。 ###持久性(Durability)
  • 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响 ##事务的隔离级别 ###多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。

###如果不考虑隔离性,可能会引发如下问题:

  1. 脏读:指一个事务读取了另外一个事务未提交的数据。

     这是非常危险的,假设A向B转帐100元,对应sql语句如下所示
     update account set money=money+100 while name=‘b’;	
     update account set money=money-100 while name=‘a’;
    
     当第1条sql执行完,第2条还没执行(A未提交时),如果此时B查询自己的帐户,就会发现自己多了100元钱。如果A等B走后再回滚,B就会损失100元。
    
  2. 不可重复读:在同一事务中,多次读取同一(同一行)数据返回的结果有所不同,也就是说后续读取可以读取另一事务针对该行数据已提交的更新数据(在一个事务内读取表中的某一行数据,多次读取结果不同。)

     例如银行想查询A帐户余额,第一次查询A帐户为200元,
     此时A向帐户内存了100元并提交了,银行接着又进行了一次查询,此时A帐户为300元了。
     银行两次查询不一致,可能就会很困惑,不知道哪次查询是准的。
    
    • 和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。

    • 很多人认为这种情况就对了,无须困惑,当然是后面的为准。我们可以考虑这样一种情况,比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中,结果在一个事务中针对输出的目的地,进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准了。

  3. 虚读(幻读):指在一个事务内读取到了别的事务插入(一行新)的数据,导致前后读取不一致。

     如丙存款100元未提交,这时银行做报表统计account表中所有用户的总额为500元,
     然后丙提交了,这时银行再统计发现帐户为600元了,
     造成虚读同样会使银行不知所措,到底以哪个为准。
    

##事务隔离性的设置语句 ###数据库共定义了四种隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)
Read committed:可避免脏读情况发生(读已提交)。
Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

###设置事务隔离级别

set   transaction isolation level 

###查询当前事务隔离级别

select @@tx_isolation	

##演示不同隔离级别下的并发问题

###1、当把事务的隔离级别设置为read uncommitted时,会引发脏读、不可重复读和虚读

	A窗口
	set transaction isolation level  read uncommitted;
	start transaction;
	select * from account;
	-----发现a帐户是1000元,转到b窗口
	select * from account
	-----发现a多了100元,这时候a读到了b未提交的数据(脏读)
	

	B窗口
	start transaction;
	update account set money=money+100 where name='aaa';
	-----不要提交,转到a窗口查询

###2、当把事务的隔离级别设置为read committed时,会引发不可重复读和虚读,但避免了脏读 A窗口 set transaction isolation level read committed; start transaction; select * from account; -----发现a帐户是1000元,转到b窗口 select * from account; -----发现a帐户多了100,这时候,a读到了别的事务提交的数据,两次读取a帐户读到的是不同的结果(不可重复读)

	B窗口
	start transaction;
	update account set money=money+100 where name='aaa';
	commit;
	-----转到a窗口

###3、当把事务的隔离级别设置为repeatable read(mysql默认级别)时,会引发虚读,但避免了脏读、不可重复读

	A窗口
	set transaction isolation level repeatable read;
	start transaction;
	select * from account;
	----发现表有4个记录,转到b窗口
	select * from account;
	----可能发现表有5条记如,这时候发生了a读取到另外一个事务插入的数据(虚读)
	
	
	B窗口
	start transaction;
	insert into account(name,money) values('ggg',1000);
	commit;
	-----转到 a窗口

###4、当把事务的隔离级别设置为Serializable时,会避免所有问题 A窗口 set transaction isolation level Serializable; start transaction; select * from account; -----转到b窗口

	B窗口
	start transaction;
	insert into account(name,money) values('ggg',1000);
	-----发现不能插入,只能等待a结束事务才能插入

##加入dbcp链接池 ###1.导入jar包 commons-dbcp-1.2.2.jar commons-pool.jar

###2、在类目录下加入dbcp的配置文件:dbcpconfig.properties

###3、在jdbcUtils的静态代码块中创建池

private static DataSource ds = null;
static{
	try{
		InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
		Properties prop = new Properties();
		prop.load(in);
		
		BasicDataSourceFactory factory = new BasicDataSourceFactory();
		
		ds = factory.createDataSource(prop);
		System.out.println(ds);
	}catch (Exception e) {
		throw new ExceptionInInitializerError(e);
	}
}

© 著作权归作者所有

abinge2016
粉丝 0
博文 10
码字总数 11597
作品 0
杭州
程序员
私信 提问
【目录】mysql 学习

数据库排行榜 http://db-engines.com/en/ranking [MySQL运维] mysql 5.1 升级编译安装5.6把原MyISAM表转换成InnoDB,并全局备份一次【原创】 http://990487026.blog.51cto.com/10133282/169...

990487026
2015/09/09
0
0
Django 事务详解

Django 1.4 事务默认模式是autocommit模式,每个查询都相当于一个事务,每次查询都直接提交commit事务, 除非事务被禁止 Django’s default behavior is to run in autocommit mode. Each query...

cooffeelis
2017/08/04
0
0
MySQL出现死锁情况

这个问题烦心一星期啦,也真是操蛋!问题描述,ecshop连接本地MySQL数据库刚刚的,链接阿里云就出现错误!一,出现500错误是因为阿里云没有添加白名单,二,出现504错误是因为MySQL上锁的问题...

slagga
2016/07/04
61
0
MySQL数据库服务器端核心参数详解和推荐配置之三

【导读】 MySQL手册上也有服务器端参数的解释,以及参数值的相关说明信息,现针对我们大家重点需要注意、需要修改或影响性能的服务器端参数,作其用处的解释和如何配置参数值的推荐,此事情拖...

鉴客
2011/11/13
330
0
Percona监控MySQL模板详解

InnoDB Adaptive Hash Index 显示了“自适应哈希索引”的使用情况,哈希索引只能用来搜索等值的查询. Hash Index Cells Total 自适应哈希表的槽数=innodbbufferpool_size/256 Hash Index Cel...

陈天刚
2018/01/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

kubernetes API 访问控制在阿里云容器服务(ACK)上的实践

提起K8s API的访问控制,很多同学应该都会想到RBAC,这是K8s用来做权限控制的方法,但是K8s对API的访问控制却不止于此,今天我们就来简单介绍下K8s的访问控制以及ACK如何利用这套方法提供便捷...

zhaowei121
18分钟前
1
0
从HelloWorld看Knative Serving代码实现

概念先知 官方给出的这几个资源的关系图还是比较清晰的: 1.Service: 自动管理工作负载整个生命周期。负责创建route,configuration以及每个service更新的revision。通过Service可以指定路由流...

迷你芊宝宝
18分钟前
1
0
如何防止http请求数据被篡改

故事的开始,面试官问了我一个问题: 如何防止http请求中数据被篡改? 回答: 1.设置客户端IP黑/白名单 1.1.客户端所有请求,请求到代理服务器(nginx),代理服务器维护黑/白名单的ip,决定是...

太猪-YJ
23分钟前
1
0
好程序员大数据笔记之:Hadoop集群搭建

在学习大数据的过程中,我们接触了很多关于Hadoop的理论和操作性的知识点,尤其在近期学习的Hadoop集群的搭建问题上,小细节,小难点拼频频出现,所以,今天集中总结以下笔记,希望对各位同学...

好程序员IT
30分钟前
1
0
MySql用navcat连接时报错 2509

在8版本以后的MySql默认的加密方式都改为了caching_sha2_password 因此进入mysql的命令行更改加密方式即可 ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER......

lanyu96
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部