数据库隔离级别(mysql+Spring)与性能分析

  数据库隔离级别与Spring配置事务的联系及性能影响,以下是个人理解,如果有瑕疵请及时指正。 这里以mysql为例,先明确以下几个问题:

  一.一般项目如果不自己配置事务的话,一般默认的是autocommit,即执行完一个操作后自动commit,提交事务。 (注:事务是绑定在数据库操作上的,也就是当程序执行(statement.excute等操作)转而到数据库层面上的时候,事务才开始发生) 当然spring可以将几个数据库操作动作绑在一个事务中,这样就需要介绍下spring事务配置方法,下面介绍的是常用方法,其他方法网上有很多。 spring提供了很多事务配置的策略,很方便,简要介绍一下: <:property name="transactionAttributes">

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED,readOnly

PROPAGATION_REQUIRED,readOnly

   一般spring配置事务都是以上的配法,具体参数的意思有不懂的上网自己查吧,那么需要注意以下几点:(题外话) 1.我习惯将事务配置在service上,这时需要注意,只有service中以save、update等开头的方法,配置的事务才有效果。如果service中的方法名不是以save等开头的,比如taskSave()方法,即使在实现类中调用了service中的update方法,配置事务也失效,我试过。 2.readOnly这个属性很有意思,因为用了它后,会自动将数据库的隔离级别提高了一级,由提交读变为重复读,这块我后面说明。

  二.数据库隔离级别 数据库隔离级别主要有以下四个:不可提交读,提交读,重复读和序列化读(以下理解可以不看)。 1. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。

  这种隔离级别会产生脏读,不可重复读和幻像读。

  2. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

  3. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

  它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

  4. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

  除了防止脏读,不可重复读外,还避免了幻像读。

  mysql默认的隔离级别是重复读,即 ISOLATION_REPEATABLE_READ。

  注意:其中未提交读与序列化读不常用,未提交读危险性太高,会读到很多脏数据。而可串行化读是通过将读取的每一行数据加锁,以耗费性能为代价换取的,所以使用也很少,大部分数据库的隔离级别是提交读,比如oracle、sqlserver。而mysql默认的数据隔离级别是可重复读。

  下面我来结合项目分析以下调整数据库隔离级别对性能的影响:

  本地mysql数据库由ISOLATION_REPEATABLE_READ级别降低到ISOLATION_READ_COMMITTED级别:

  场景:未用Spring,用户A在一个事务中对数据库发出两次查询请求,在两次查询之间,用户B对数据库的记录进行修改。

  结果:ISOLATION_REPEATABLE_READ级别:用户A两次查询结果不一样。

  ISOLATION_READ_COMMITTED级别:用户A两次查询结果一样,因为对记录进行了加锁操作。

  以task模块为例,在本地运行任务首页,通过对比分析两种事务处理方式得到如下结果(每次统计数据前均清理浏览器缓存,统计3次取平均值):


  发现降低数据库事务的隔离级别,对于一些特殊逻辑的操作上,性能有所提升。

  但是如果查询过程中,不涉及同一事务中多次对数据库操作的复杂逻辑及同一事务中多次查询同一结果集的逻辑,则对速度的提升效果并不明显,即事务进行时对数据集加锁的时间是可以忽略的,下面再来理解一下事务隔离级别与锁的关系。

  谈到数据库隔离级别,就要说一下锁的概念: 主要分为共享锁和排他锁。 共享锁:由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写

  排它锁:由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务中。

  个人理解:共享锁和排他锁没有严格的界限,我认为应该通过结果确定加的是共享锁还是排他锁。

  例如:用户A修改一条数据,用户B也修改这条数据,挂起。 但是B查看这个数据可以,证明A用户添加了行级共享锁。

  再例如:用户A修改一条数据,用户B查询这条数据失败,查询其他数据也失败。那么肯定A加了表级排他锁。

  再例如:用户A修改一条数据,用户B查询记录可以,但是修改这条记录不行,修改其他记录也不行,那么A加了表级共享锁。

  不同的数据隔离级别,加的锁是不一样的。

  回到前面的问题,readonly属性一旦被设置后,数据库级别如果为提交读,那么同一个事务中,如果对两次结果集进行查询,中间间隔修改数据库,那么应该会是同一个结果集,相当于查询的时候采用的是重复读的隔离级别。

时间: 2024-09-04 23:51:56

数据库隔离级别(mysql+Spring)与性能分析的相关文章

mysql+Spring数据库隔离级别与性能分析_Mysql

这里以mysql为例,先明确以下几个问题: 一.一般项目如果不自己配置事务的话,一般默认的是autocommit,即执行完一个操作后自动commit,提交事务. (注:事务是绑定在数据库操作上的,也就是当程序执行(statement.excute等操作)转而到数据库层面上的时候,事务才开始发生)当然spring可以将几个数据库操作动作绑在一个事务中,这样就需要介绍下spring事务配置方法,下面介绍的是常用方法,其他方法网上有很多.spring提供了很多事务配置的策略,很方便,简要介绍一下: 复

数据库隔离级别

数据库隔离级别有四种,应用<高性能mysql>一书中的说明:   然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. 2 [mysqld] 3 transaction-isolation = REPEATABLE-READ 这里全局默认是REPEATABLE-READ,其实MySQL本来默认也是这个级别 2.

数据库锁和数据库隔离级别

最近突然发现忘了数据库锁和数据库隔离级别,时常弄混它们之间的关系.为此特此写下此博客,以方便自己复习,同时也可以帮助博友. 数据库锁 数据库锁就是事务T在对某个数据对象(例如表.记录等)操作之前,先向系统发出请求,对其加锁.加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象. 数据库锁是实现并发控制的重要技术,但是"锁"会带来系统额外的开销.所以需要注意选择封锁粒度时必须同时考虑开销和并发度两个因素,进行权衡,以求得最优的效果. 锁的类型主要

mysql事务隔离级别与spring事务配置

问题描述 代码:voidfun(){Useruser=newUser();user.setId(1);user.setName("aaa");update(user);UsernewUser=select(1);//这里查询出的newUser的name还是更新前的值.}voidupdate(Useruser){//更新用户信息}Userselect(id){//根据id查询用户信息} 使用spring配置的事务的时候,上面方法fun.update被spring配置了事务propagat

spring事务中隔离级别和spring的事务传播机制

Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是一个不可分割的整体,就像我们在化学课里学到的原子,原子是构成物质的最小单位.于是,人们就归纳出事务的第一个特性:原子性(Atomicity).我靠,一点都不神秘嘛. 特别是在数据库领域,事务是一个非常重要的概念,除了原子性以外,它还有一个极其重要的特性,那就是:一致性(Consistency).也就

oracle 数据库隔离级别学习_oracle

oracle 事务隔离级别 事务不同引发的状况: 脏读(Dirty reads) 一个事务读取另一个事务尚未提交的修改时,产生脏读 很多数据库允许脏读以避免排它锁的竞争. 不可重复读(Nonrepeatable reads) 同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读. 幻读(Phantom reads) 同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读. 数据库操作的隔离级别 未提交读

mysql数据库优化与mysql在web性能优化

数据库语句:     Ddl(数据定义语言)    alter  create   drop         Dml(数据操作语言)   inset  delete  update       Dtl(数据事务语言)  conmmit  rollback   savepoint       Select       Dcl(数据控制语句) grant赋权限  revoke回收        Mysql数据库优化: 1.  数据库表 要设计合理(符合3NF,有时候也需要适当的逆范式) 2.  Sq

数据库隔离级别在项目哪个地方配置

问题描述 如题 解决方案 解决方案二:获取到Connection对象后调用其setTransactionIsolation方法设定.或获取连接的时候作为连接属性配入.解决方案三:在xml文件中配置的吧.解决方案四:这个我只记得在.NET是必须配的··解决方案五:一般applicationserver提供jndi数据源配置.所以一般在server提供数据源配置里面来设.

SQL-92隔离级别理解和测试

以前对数据库的隔离级别,有所了解,但不知道真正其中的区别.今天就讨论一下这4个隔离级别 下面是4个隔离级别,在SQL server 2005里的介绍: READ UNCOMMITTED 指定语句可以读取已由其他事务修改但尚未提交的行. READ COMMITTED 指定语句不能读取已由其他事务修改但尚未提交的数据.这样可以避免脏读.其他事务可以在当前事务的各个语句之间更改数据,从而产生不可重复读取和幻像数据 REPEATABLE READ 其他事务可以插入与当前事务所发出语句的搜索条件相匹配的新