neverend的日志

不记录,终将被遗忘。 一万年太久,只争朝夕。 他们用数字构建了整个世界。

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  62 Posts :: 1 Stories :: 17 Comments :: 0 Trackbacks

2011年8月19日 #

在事务隔离级别设定为repeatable read的情况下,一般的select语句采取的是一致性非阻塞读的方式。
一致性是指在事务的范围内读取的数据是可重现的,不会出现不可重复读的情况。非阻塞是指这种读取数据的模式不会对数据上任何一种锁,其它操作全都不会被阻塞。
在这种模式下,事务执行读取语句后,相关的数据会有一套副本出现,并会为这个数据副本附加一个时间戳,其它事务在这个时间戳之后执行的写操作都不会反映到这个副本中,这种机制被称之为多版本并发控制。
如果用select …… lock in share mode,则不是一致性非阻塞读,该语句会等待其它事务的写语句提交或回滚之后再读取数据;如果事务隔离级别设置为read committed,也不是一致性非阻塞读,该语句会读取其它事务提交的数据。
posted @ 2012-04-05 11:25 neverend 阅读(1860) | 评论 (0)编辑 收藏

介绍下对于Mysql锁机制的理解
从基本概念开始:
共享锁
共享锁的代号是S,是Share的缩写,共享锁的锁粒度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。

排它锁
排它锁的代号是X,是eXclusive的缩写,排它锁的粒度与共享锁相同,也是行或者元组。一个事务获取了排它锁之后,可以对锁定范围内的数据执行写操作。

假设有两个事务t1和t2
如果事务t1获取了一个元组的共享锁,事务t2还可以立即获取这个元组的共享锁,但不能立即获取这个元组的排它锁(必须等到t1释放共享锁之后)。
如果事务t1获取了一个元组的排它锁,事务t2不能立即获取这个元组的排共享锁,也不能立即获取这个元组的排它锁(必须等到t1释放排它锁之后)。
 
意向锁
意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁(IS)和意向排它锁(IX)两类。意向共享锁表示一个事务有意对数据上共享锁或者排它锁。“有意”这两个字表达的意思比较微妙,说的明白点就是指事务想干这个事但还没真去干。举例说明下意向共享锁,比如一个事务t执行了这样一个语句:select * from table lock in share model ,如果这个语句执行成功,就对表table上了一个意向共享锁。lock in share model就是说事务t1在接下来要执行的语句中要获取S锁。如果t1的select * from table lock in share model执行成功,那么接下来t1应该可以畅通无阻的去执行只需要共享锁的语句了。意向排它锁的含义同理可知,上例中要获取意向排它锁,可以使用select * from table for update

lock in share model 和 for update这两个东西在数据率理论中还有个学名叫悲观锁,与悲观锁相对的当然还有乐观锁。大家可以看到各种锁都是成双成对出现的。关于悲观锁和乐观锁的问题暂且不表,下文再来详述。

锁的互斥与兼容关系
锁和锁之间的关系,要么是相容的,要么是互斥的。
锁a和锁b相容是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2还可以获取锁b;
锁a和锁b互斥是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2在t1释放锁a之前无法获取锁b。

上面提到的共享锁、排它锁、意向共享锁、意向排它锁相互之前都是有兼容/互斥关系的,可以用一个兼容性矩阵表示(y表示兼容,n表示不兼容):
    X    S    IX    IS
X  n     n    n     n
S  n     y    n     y
IX n     n    y     y
IS n     y    y     y 

兼容性矩阵为什么是这个样子的?
X和S的相互关系在上文中解释过了,IX和IS的相互关系全部是兼容,这也很好理解,因为它们都只是“有意”,还处于YY阶段,没有真干,所以是可以兼容的;
剩下的就是X和IX,X和IS, S和IX, S和IS的关系了,我们可以由X和S的关系推导出这四组关系。
简单的说:X和IX的=X和X的关系。为什么呢?因为事务在获取IX锁后,接下来就有权利获取X锁。如果X和IX兼容的话,就会出现两个事务都获取了X锁的情况,这与我们已知的X与X互斥是矛盾的,所以X与IX只能是互斥关系。其余的三组关系同理,可用同样的方式推导出来。

一致性非阻塞读

select... lock in share mode和select ... for update的区别

索引记录锁
间隙锁
后码锁

各种语句对应的锁类型
在有索引的情况下是以后码锁为基础的行级锁,在固定索引键查找的情况下是索引记录锁,在没有可用索引的情况下上升到表锁
有索引的情况:
select ... from 一致性非阻塞读,不上锁。在serializable隔离级别下例外,在这个隔离级别下上共享后码锁
select ... from ... lock in share mode  共享后码锁
select ... from ... for update 排它后码锁
update .... where  排它后码锁
delete from .... where 排它后码锁
insert ... 排它索引记录锁,如果发生键值唯一性冲突则转成共享锁
insert ... on duplicate key update ,一直都是排它锁
replace ... 一直都是排它锁


死锁情境分析

MVCC的理论与实现
posted @ 2012-03-31 14:53 neverend| 编辑 收藏

1. 优化更需要优化的SQL
高并发低消耗 > 低并发高消耗

2. 定位性能瓶颈
profiling

3. 明确的优化目标

4. 从explain入手
y
5. 小结果集驱动大结果集??
Join操作

6. 在索引中完成排序

7. 只取出自己需要的columns
MySQL有两种排序算法,尽可能使用只访问一次数据的算法。

8. 仅仅使用最有效的过滤条件
索引键长度?

9. 避免复杂的join和子查询

充分利用EXPLAIN和profiling
profiling的使用:
1.set profiling = 1;
2.执行SQL;
3.show profile;
4.show profile [cpu, block io] for query [id];

mysqlslap 测试sql性能
mysqlslap --concurrency=5 --iterations=500 --query="selec
t * from hbe_hotel" --create-schema=phoenix -uroot -p

合理设计并使用索引
Mysql支持的索引类型:
1. B-tree索引 除了Archive的存储引擎都支持
2. Hash索引  memory和NDB支持
3. Full-text索引 MyISAM,分词后建立B-tree索引
4. R-tree索引 MyISAM ,GIS系统使用

索引的利弊
利:提高数据检索效率和排序、分组效率
弊:加大更新操作的资源消耗,增加存储空间的消耗

如何判断是否需要使用索引
1. 使用较频繁的字段应该创建索引
2. 唯一性太差的字段不建索引 经验值:15%
3. 更新非常频繁的字段不建索引
4. where子句中不出现的字段不建索引

单键索引还是组合索引?
多方考虑,平衡优劣

技术人员如何证明一个需求是否合理?
1. 每次PD提出新需求的时候,要求给出该项目预期收益的量化指标。
2. 在项目进行中,详细记录所有资源投入,包括人力、硬件等。
3. 项目上线后收集数据统计实际收益值。
4. 相关部门尽可能设计出项目投入/产出比率的计算规则,将投入/产出比公布给参与项目的所有人员。
5. 比较实际的投入/产出比与预期值,以判定项目做的是否值得。

posted @ 2012-03-13 07:48 neverend 阅读(347) | 评论 (0)编辑 收藏

MySQL执行计划 

调用方式:
explain select ...

explain extended select ...
show warnings 得到MySQL优化器优化后的查询语句

执行计划包含的信息:


说明:
id: select子句的优先级,id越大,优先级越高。
select_type: 查询类型
table: 查询的表名
type:  MySQL找到所需行使用的方式,包括如下类型:


ALL: 扫描全表
index: 扫描全部索引树
range: 扫描部分索引
ref: 非唯一性索引扫描
eq_ref:唯一性索引扫描
const, system: MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引

rows: 找到所需记录需要读取的行数
Extra: 额外信息

执行计划可用来分析select语句的性能,排查性能瓶颈。

参考资料:
http://wenku.baidu.com/view/d4416c27aaea998fcc220ea7.html

/Files/neverend/mysqlexplain-MySQL执行计划解读.ppt
posted @ 2012-02-04 18:33 neverend 阅读(710) | 评论 (0)编辑 收藏

头疼的SVN代码merge问题

如何merge代码?
建议用命令搞merge,客户端图形界面不是很给力。
SVN 1.5以上版本,可以使用SVN的自动合并:
将主干合并到分支:
进入分支目录,执行命令: svn merge http://server/dir/trunk

将分支合并到主干:
进入主干目录,执行命令: svn merge http://server/dir/branch  --reintegrate
注: 如果之前进行过主干合并到分支的操作,请加参数--reintegrate,否则可能会有很多代码冲突出现。

如果是SVN1.5以下版本,只能使用手工合并:
进入主干目录,执行命令:svn merge -r version1:version2 http://server/dir/branch
将branch上从version1到version2所做的改动合并到主干,vension1 < version2

进入主干目录,执行命令: svn merge -c version1 http://server/dir/branch
表示将version1次所做的改动合并到主干

代码冲突如何解决?

conficted

tree conficted
posted @ 2012-02-04 18:13 neverend 阅读(2070) | 评论 (0)编辑 收藏

项目开发过程中经常会碰到maven依赖冲突的问题,这篇post整理下maven依赖冲突产生的原因以及解决方案

maven依赖冲突的产生是由maven传递性依赖造成的:

什么是maven传递依赖?
“一个传递性依赖就是对于一个依赖的依赖。如果project-a依赖于project-b,而后
者接着依赖于project-c,那么project-c就被认为是project-a的传递性依赖。如
果project-c依赖于project-d,那么project-d就也被认为是project-a的传递性依
赖。Maven的部分吸引力是由于它能够管理传递性依赖,并且能够帮助开发者屏蔽掉跟
踪所有编译期和运行期依赖的细节。你可以只依赖于一些包如Spring Framework,而不
用担心Spring Framework的所有依赖,Maven帮你自动管理了,你不用自己去详细了解
配置。
Maven是怎样完成这件事情的呢?它建立一个依赖图,并且处理一些可能发生的冲突和
重叠。例如,如果Maven看到有两个项目依赖于同样的groupId和artifactId,它会自动
整理出使用哪个依赖,选择那个最新版本的依赖。虽然这听起来很方便,但在一些边界
情况中,传递性依赖会造成一些配置问题。在这种情况下,你可以使用依赖排除。”
                                                             ——摘自《Maven权威指南》

什么情况下会产生依赖冲突?
举例说明:项目中的pom.xml里声明了对project-a1.0与project-b2.0的依赖,而project-a1.0又传递依赖于project-b1.0的版本。
假设maven经过分析之后决定使用project-b1.0的依赖,也就是打包的时候把project-b1.0.jar打进了war包。
war包部署在java容器中启动之后,如果依赖project-b2.0.jar中新添的类或方法,就会发现引用的类或者方法不存在。
这种现象就是依赖冲突。

如何分析依赖冲突?
mvn dependency:tree

冲突解决方案:
使用maven提供的<exclusion>标签。
举例说明:
如果你正依赖于一个类库,该类库又依赖于Sun JTA API,你会想要替换这个传递性依赖。
Hibernate是一个例子。Hibernate依赖于Sun JTA API,而后者在中央Maven仓库中不可用,因为它是不
能免费分发的。幸运的是,Apache Gernoimo项目创建了一些可以免费分发的独立实现
类库。为了用另外的依赖来替换这个传递性依赖,你需要排除这个传递性以依赖,然后
在你的项目中再声明一个依赖。下面展示了这样一个替换的样例。
<dependency>
    
<groupId>org.hibernate</groupId>
    
<artifactId>hibernate</artifactId>
    
<version>3.2.5.ga</version>
    
<exclusions>
        
<exclusion>
            
<groupId>javax.transaction</groupId>
            
<artifactId>jta</artifactId>
        
</exclusion>
    
</exclusions>
</dependency>
<dependency>
    
<groupId>org.apache.geronimo.specs</groupId>
    
<artifactId>geronimo-jta_1.1_spec</artifactId>
    
<version>1.1</version>
</dependency>


posted @ 2012-02-03 15:51 neverend 阅读(1954) | 评论 (1)编辑 收藏

讨论MySQL死锁问题

死锁分析
posted @ 2012-02-01 22:37 neverend 阅读(386) | 评论 (0)编辑 收藏

总结缓存技术
posted @ 2012-02-01 22:36 neverend 阅读(709) | 评论 (1)编辑 收藏

关于JAVA注解,已经不止一次的碰到了,但是没有系统的研究过。

最近打算搞清楚以下问题:

1. 注解的原理与使用
2. Java提供的标准注解分析。
3. Spring与Junit的常用注解分析。
4. 如何合理的设计和使用注解

1. 注解的原理与使用
    阅读了《Java编程思想》讲注解的一章,整理笔记如下:
    1.1 定义注解
    使用元注解定义注解,元注解有四种:
    @Target(ElementType.[type])
    [type]={METHOD, FIELD, TYPE(类、接口、枚举声明), CONSTRUCTOR, LOCAL_VARIABLE, PARAMETER}
    @Retention(RetentionPolicy.[policy])
    [policy]={SOURCE, CLASS, RUNTIME(反射机制可读取)}
    @Documented 表示将此注解包含到Javadoc中
    @Inherited 表示允许子类继承父类的注解
    例子:
//:annotations/UserCase.java

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCases {
    public int value() default 0;
    
public int id() default 0;
    
public String description() default "no description";
}
   
    1.2使用注解
        @UserCase(id=10, description="my desccription")
        注意:
        注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定
        非基本类型的注解元素的值不可为null
        注解快捷方式: 如果注解元素声明为value(),则在使用注解时如果只声明value,可以只写值,不必写名值对。例如可写为@UseCase(10)
    1.3编写注解处理器
        通过反射机制获取注解元素的值: Method.getAnnotation(), Field.getDeclaredAnnotations()等方法
    1.4注解的使用场景
        统计系统用例实现情况   
        由JavaBean自动生成数据库建表SQL
    1.5 JDK提供的注解工具apt
    1.6 基于注解的单元测试    
待续……
2. Java提供的标准注解分析。
    @Override
/*
 * @(#)Override.java    1.5 04/02/09
 *
 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 
*/


package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a superclass.  If a method is annotated with
 * this annotation type but does not override a superclass method,
 * compilers are required to generate an error message.
 *
 * 
@author  Joshua Bloch
 * 
@since 1.5
 
*/

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

    注解@Override的代码非常简单,可用于注解类的方法,并在Source级别可用。  
    @Deprecated
    级别为Runtime    
  
    @SuppressWarnings
    级别为source,经常的使用方式为@SuppressWarnings("unchecked")
3. Spring与Junit的常用注解分析。
    @Test
   
4. 如何合理的设计和使用注解
    使用注解标记字段和方法,可通过反射的手段截取注解及其标记的字段和方法的元数据,并根据需求对元数据进行处理。
    它赋予了字段和方法额外的意义,提供了一种统一处理字段和方法的优雅的方式。
    注解更多的意义是提供了一种设计模式,在本质上它没有增强Java的能力,使用注解实现的功能都可以以非注解的方式实现,只是代码可能不是很好看而已
posted @ 2012-01-30 11:16 neverend 阅读(20051) | 评论 (2)编辑 收藏

先配置好环境变量$TOMCAT_HOME

在/etc/init.d/目录下新建文件tomcat,输入如下内容:
#! /bin/sh
# This shell script enables the automatic use of tomcat
#
# Author:      liuxuanyu<neverend06@163.com>
#

RETVAL=0

start() {
    echo -n "Tomcat Starting..."
 echo
 $TOMCAT_HOME/bin/startup.sh
}

stop() {
    echo -n "Tomcat Stop..."
 echo
 $TOMCAT_HOME/bin/shutdown.sh
}

restart() {
 echo -n "Tomcat restart..."
 echo
 stop
 start
}

case "$1" in
 start)
      start;;
 stop)
   stop;;
 restart)
      restart;;
 *)
    echo $"Usage: $0 {start|stop|restart}"
 exit 1
esac

exit $RETVAL

使用方法:
sudo /etc/init.d/tomcat start
sudo /etc/init.d/tomcat stop
sudo /etc/init.d/tomcat restart

posted @ 2011-08-19 23:00 neverend 阅读(1116) | 评论 (0)编辑 收藏