存档

2010年1月 的存档

事务(数据库引擎)

2010年1月28日 stone 没有评论

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为原子性一致性隔离性持久性 (ACID) 属性,只有这样才能成为一个事务。

原子性
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
一致性
事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。
隔离
由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务识别数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是第二个事务修改它之后的状态,事务不会识别中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。
持久性
事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。

 

数据库引擎隔离级别

ISO 标准定义了关系型数据库的隔离级别:

  • 未提交读 Read Uncommitted(隔离事务的最低级别,只能保证不读取物理上损坏的数据) :  允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
  • 已提交读 Read Committed(数据库引擎的默认级别,只能读取到已经提交的数据) :   允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
  • 可重复读 Repeated Read   :  禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
  • 可序列化(串行读) Serializable(隔离事务的最高级别,事务之间完全隔离)  :  提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

         *   SQL Server 和Oracle 默认隔离级别为Read Commited ;MySQL InnoDB存储引擎默认的隔离级别为Repeatable Read。
         *   隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

下表显示了不同隔离级别导致的并发副作用。

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
未提交读 Read Uncommitted
已提交读 Read Committed
可重复读 Repeated Read
可序列化 Serializable

 

  • 脏读 Dirty Read   ( 一个事务读取了另一个未提交的并行事务写的数据)
  • 不可重复读 NonRepeatable Read (一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务修改过)
  • 幻读 Phantom Read (一个事务重新执行一个查询,返回一套符合查询条件的行,发现这些行因为其他最近提交的事务而发生了改变)

        *   Dirty Read    如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
             解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可以避免该问题。

        *   NonRepeatable Read    如事务A中两处读取数据 price 的值,在第一读的时候,price 是10,然后事务B就把 price 的数据改成20,事务A再读一次,结果就发现,price 竟然就变成20了,造成事务A数据混乱。
             解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

        *   Phantom Read    与NonRepeatable Read相似,也是同一个事务中多次读不一致的问题。NonRepeatable Read的不一致是因为它所要取的数据集被改变了(比如price 的数据),但 Phantom Read 所要读的数据的不一致却不是它所要读的数据集改变,而是它的条件数据集改变。比如事务A Select count(*) from students where  class='1' ;  第一次读了班级1的学生人数为35,第二次读取的时候,由于事务B插入或者删除一个班级为1的学生,结果取出来了36或34。
             解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题。

分类: Note 标签: ,

直言有讳

2010年1月28日 stone 没有评论
原文:http://blog.sina.com.cn/s/blog_3f09617e0100849v.html
 
    见到一个很丑的人。三岁的孩子说:他真丑。这叫说真话。
    十三岁的孩子说同样的话,叫不懂事。
    二十三岁的人如果这么说,则是没修养。
 
    所谓‘诚实’诚在先,实在后,‘诚’是善意和尊重。生活不需要说出全部的真相。真话也不可以随意说,一吐为快的‘真话’有时比谎言更加伤人。
    实话直说只需要勇气,而说话不伤人则需要修养和智慧。   
分类: Other 标签:

SUN JDK JVM Heap

2010年1月14日 stone 没有评论

JVM Heap

(1)young generation

年轻代分三个区。一个Eden区,两个Survivor区。大部分对象在 Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到tenured generation。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。
young generation的gc称为minor gc。经过数次minor gc,依旧存活的对象,将被移出young generation,移到tenured generation

(2)tenured generation

生命周期较长的对象,归入到tenured generation。一般是经过多次minor gc,还 依旧存活的对象,将移入到tenured generation。(当然,在minor gc中如果存活的对象的超过survivor的容量,放不下的对象会直接移入到tenured generation)
tenured generation的gc称为major gc,就是通常说的full gc。
采用compaction算法。由于tenured generaion区域比较大,而且通常对象生命周期都比较长,compaction需要一定时间。所以这部分的gc时间比较长。
minor gc可能引发full gc。当eden+from space的空间大于tenured generation区的剩余空间时,会引发full gc。这是悲观算法,要确保eden+from space的对象如果都存活,必须有足够的tenured generation空间存放这些对象。

(3)permanent generation

该区域比较稳定,主要用于存放classloader信息,比如类信息和method信息。
对于spring hibernate这些需要动态类型支持的框架,这个区域需要足够的空间。(这部分空间应该存在于方法区而不是heap中)。

分类: Note 标签: , ,

[MySQL] 相关SQL语句

2010年1月14日 stone 没有评论

连接数据库:mysql [host] –u [user] –p
查看数据库:show databases;  列出数据库服务器上所有数据库
查看当前使用的数据库:select database(); 
使用数据库:use [database name]  ; 切换到需要操作的数据库
查看表:      show tables;  列出当前所在数据库的所有表
查看表结构:describe [table name] ;  查看表结构

数据库的授权:grant all privileges on *.* to 'root'@'localhost' identified by 'zg'
这句话的意思是让用户root可以从localhost登陆,并对所有的数据库有权限,密码是zg
它相当于在数据库mysql的user表中添加了一条记录,此表以user与host为主键
如想更新密码可以这样:update user set password=password(密码) where user=? and password=?

导入.sql文件(该文件包含表及相关数据):
[root@mylocal001 ~]# mysql -u root -p posdb < /soft/war/posdb.sql

LIMIT子句
MS SQLSERVER 中有SELECT TOP语句, Oracle中有ROWNUM序列,那么MYSQL中如何实现select top n效果?
使用Mysql中的LIMIT子句
用法: select * from Table limit n,m;
limit n,m的含义是从n开始取,取m条记录

*当使用update语句时,LIMIT子句用于给定一个限值,限制可以被更新的行的数目。
update Table set col_name1=expr1 [, col_name2=expr2 ...] limit 1000;

查看系统中支持的存储引擎类型:show engines;
查看某个存储引擎的具体信息: show engine InnoDB status;
创建表时指定存储引擎的类型: CREATE TABLE tablename (id int, title char(20)) ENGINE = INNODB;
修改现有的表使用的存储引擎:  ALTER TABLE tablename ENGINE = MyISAM;
查看某个库中所有表的存储引擎:show table status from DBName;
查看某个库中单个表的存储引擎:show create table DBName.TableName;

查看Mysql版本(三种方法):
mysql>status;
mysql>select version();
[root@mylocal001 ~] # mysql -V

分类: Note 标签:

马尼拉中添加Live mail邮箱

2010年1月7日 stone 没有评论

MNL

马尼拉中邮箱设置中由于没有Live mail邮箱类型,而我的 stone@hugstone.com 邮箱是Live Mail邮箱.经过一番折腾终于将Live邮箱添加成功.

在Mail Setup中输入Email address和Password后,选择Manual Setup,

Incoming mail server设为pop3.live.com
(*注意的下面的用户名请输入完整的Email address)

Outgoing (SMTP) mail server设为smtp.live.com

完成后,就能成功收发Live mail邮件了.

分类: Diary 标签: