随笔-14  评论-142  文章-0  trackbacks-0
  2006年6月15日

1, 脏读

一个事务读到另一个事务,尚未提交的修改,就是脏读。这里所谓的修改,除了Update操作,不要忘了,还包括
Insert和Delete操作。

脏读的后果:如果后一个事务回滚,那么它所做的修改,统统都会被撤销。前一个事务读到的数据,就是垃圾数据。


举个例子:预订房间。
有一张Reservation表,往表中插入一条记录,来订购一个房间。

 事务1:在Reservation表中插入一条记录,用于预订99号房间。

 事务2:查询,尚未预定的房间列表,因为99号房间,已经被事务1预订。所以不在列表中。

 事务1:信用卡付款。由于付款失败,导致整个事务回滚。
        所以插入到Reservation 表中的记录并不置为持久(即它将被删除)。

现在99号房间则为可用。
所以,事务2所用的是一个无效的房间列表,因为99号房间,已经可用。如果它是最后一个没有被预定的房间,那么这将是一个严重的失误。

注:脏读的后果很严重。

 

2,不可重复读。

在同一个事务中,再次读取数据时【就是你的select操作】,所读取的数据,和第1次读取的数据,不一样了。就是不可重复读。

举个例子:
 事务1:查询有双人床房间。99号房间,有双人床。

 事务2:将99号房间,改成单人床房间。

 事务1:再次执行查询,请求所有双人床房间列表,99号房间不再列表中了。也就是说,
               事务1,可以看到其他事务所做的修改。


在不可重复读,里面,可以看到其他事务所做的修改,而导致2次的查询结果不再一样了。
这里的修改,是提交过的。也可以是没有提交的,这种情况同时也是脏读。

如果,数据库系统的隔离级别。允许,不可重复读。那么你启动一个事务,并做一个select查询操作。
查询到的数据,就有可能,和你第2次,3次...n次,查询到的数据不一样。一般情况下,你只会做一次,select
查询,并以这一次的查询数据,作为后续计算的基础。因为允许出现,不可重复读。那么任何
时候,查询到的数据,都有可能被其他事务更新,查询的结果将是不确定的。


注:如果允许,不可重复读,你的查询结果,将是不确定的。一个不确定的结果,你能容忍吗?


3,幻读

 

事务1读取指定的where子句所返回的一些行。然后,事务2插入一个新行,这个新行也满足事务1使用的查询
where子句。然后事务1再次使用相同的查询读取行,但是现在它看到了事务2刚插入的行。这个行被称为幻象,
因为对事务1来说,这一行的出现是不可思议的。

举个例子:
事务1:请求没有预定的,双人床房间列表。
事务2:向Reservation表中插入一个新纪录,以预订99号房间,并提交。
事务1:再次请求有双人床的未预定的房间列表,99号房间,不再位于列表中。


注:幻读,针对的是,Insert操作。如果事务2,插入的记录,没有提交。那么同时也是脏读。

 

 

 

 

 

 


 

posted @ 2009-04-13 12:37 liulang 阅读(7142) | 评论 (0)编辑 收藏

 clob = rs.getClob(fieldName);

 String  rtn=clob.getSubString((long)1,(int)clob.length());

posted @ 2009-04-08 12:17 liulang 阅读(3043) | 评论 (3)编辑 收藏
在resin3.0中,deploy是默认的发布目录,在MyEclipse中直接发布到resin的deploy目录中,起动服务器就会运行发布的项目,而在resin-3.1.1中发布到deploy目录下的项目不回运行,需要修改conf目录下的resin.conf文件,用editplus等文本编辑器打开,大概在229行左右,有一行 <web-app-deploy path="webapps"/>是建产发布目录路径的,我们在后边加上一行 <web-app-deploy path="deploy"/>,这样在deploy目录下的项目就能正常运行了。
posted @ 2009-04-07 10:22 liulang 阅读(616) | 评论 (0)编辑 收藏
     摘要: java折半查找算法  阅读全文
posted @ 2007-09-06 18:02 liulang 阅读(5116) | 评论 (4)编辑 收藏
     摘要: 这是面试的时候,最后一道算法题, 可能不习惯手写代码, 做错了,太没面子了...
回来一上机就写出来了!
  阅读全文
posted @ 2007-09-05 17:04 liulang 阅读(6338) | 评论 (5)编辑 收藏
     摘要: 面试老考这个,都背熟了
  阅读全文
posted @ 2007-09-05 16:58 liulang 阅读(94556) | 评论 (32)编辑 收藏
     摘要:   阅读全文
posted @ 2006-10-04 06:47 liulang 阅读(515) | 评论 (0)编辑 收藏

静态单链表 :

线性表的静态单链表存储结构 :

#define MAXSIZE 100;

 

typedef struct{

 

  ElemType data;

  int cur;

 

}component,SLinkList[MAXSIZE];

 

分析 :

这种描述方法便于在不设 指针 类型的高级程序设计语言中 , 使用的链表结构 . 数组的零分量可看成头节点 . 这种结构仍然需要预先分配一个较大的空间 . 但在插入和删除的时候 , 不需要移动元素 . 仅需要修改指针 . 所以仍然具有链式存储结构的主要优点 .

 

基本操作 :

(1)    在静态单链表中 , 查找第一个值为 e 的元素 .

int LocateElem_L(SLinkList S, ElemType e)

{

 

   i = S[0].cur;

   while(i && S[i].data != e) i=S[i].cur;

   return i;

 

}

分析 :

如果找不到相应的元素 , 返回值为 0.


(2)      将一维数组 space 中的各个分量 , 链成一个备用的链表 .

space[0].cur 为头指针 .

 

void InitSpace(SLinkList &space){

 

 

   for(i =0;i<MAXSIZE-1;++i)

      space[i].cur = i+1;

   space[MAXSIZE-1].cur =0;

 

}

 

(3)    如果备用空间的链表非空 , 则返回分配的节点下标 ,

否则 , 返回 0;

 

int Malloc_SL(SLinkList &space){

 

   i=space[0].cur;

   if(space[0].cur)

      space[0].cur =space[i].cur;

   return i;

}

(4) 将下标为 k 的空闲节点回收到备用链表 .

void Free_SL(SLinkList &space,int k)

{

space[k].cur =space[0].cur;

space[0].cur = k;

}


(4)    计算集合运算 (A-B ) (B-A)

假设由终端输入集合元素 , 先建立表示集合 A 的静态链表 S, 然后在输入集合 B 的元素的同时查找 S , 如果存在相同的元素 , 则从 S 表中删除 , 否则将其插入到 S 表中 .

具体代码如下 :

void difference(SLinkList &space , int &s)

{

 

      InitSpace_SL(space);

      s = Malloc_SL(space);

      r=s;

      scanf(m,n);

      for(j=1;j<=m;++j)

{     i =Malloc_SL(space);

           scanf(space[i].data);

           space[r].cur =i;

           r=i;

      }  space[r].cur=0;

for (j=1;j<=n;++j){

    scanf(b);

    p=s;k=space[s].cur;

    while(k!=space[r].cur && space[k].data !=b)

    { p=k;k=space[k].cur;}

if (k==space[r].cur)

{

       i = Malloc_SL(space);

       space[i].data = b;

       space[i].cur = space[r].cur;

       space[r].cur = i;

       r=i;

    }

    else{

      space[p].cur =space[k].cur;

      Free_SL(space,k);

      if(r==k)

      r=p;

    }

}

}

posted @ 2006-06-16 01:06 liulang 阅读(1146) | 评论 (0)编辑 收藏

线性表的链式存储结构 :

链式存储表示 :

typedef struct LNode{

 

  ElemType   data;

  Struct LNode *next;

 

}LNode,*LinkList;

基本操作在链表上的实现 :

(1)    单链表的取元素算法(经典

Status GetElem_L(LinkList L, int i,ElemType &e)

{

 

p=L->next; j=1;

while(p && j<i)

{

      p=p->next;++j;

}

if(!p || j>i) return ERROR;

e=p->data;

return OK;

 

}

算法分析 :

基本操作是 : 比较 j I, 并把指针后移 , 循环体执行的次数 , 与被查元素的位置有关 . 假设表长为 n, 如果 1<=i<=n, 那么循环体中语句的执行次数为 i-1. 否则次数为 n 所以时间复杂度为 O(n).

 

  (2)    插入元素算法

Status ListInsert_L(LinkList &L, int i,ElemType e)

{

 

   p=L;j=0;

   while(p&&j<i-1)

      { p=p->next;++j}

   if(!p || j>i-1)

      return ERROR;

 

   s = (LinkList)malloc(sizeof(LNode));

   s->data = e;

   s->next = p->next;

   p->next =s;

   return OK;

}
(3)    删除元素算法

Status ListDelete_L(LinkList &L, int i,ElemType &e)

{

   p=L;j=0;

while(p &&j<i-1)

   {p=p->next;++j}

if(!p ||j>i-1)

      return  ERROR;

  

q=p->next;

   p->next =q->next;

   e =q->data;

   free(q);

   return OK;

}

 

算法分析 :

插入和删除算法 , 都要先找到第 i-1 个节点 , 所以时间复杂度为 O(n);

  (4)    单链表的建立算法

 

void CreateList_L(LinkList &L,int n){

 

 L =(LinkList)malloc(sizeof(LNode));

 

 L->next = null;

  for(i = n;i>0;--i){

 

  p =(LinkList)malloc(sizeof(LNode));

  scanf(&p->data);

  p->next = L->next;

  L->next =p;

  }

 

}

算法分析 :

按照逆序循环输入 n 个数据元素的值 , 建立新节点 . 并插入 . 因此算法的时间复杂度为 O(n).


posted @ 2006-06-16 01:04 liulang 阅读(871) | 评论 (3)编辑 收藏
线性表 :
是 n(n>=0) 个相同特性数据元素的有序序列 .
  顺序存储结构和实现
线性表的顺序存储结构 , 可以随机存取 . 逻辑上相邻的两个元素 , 在物理存储上也是相邻的 . 顺序存储表示 :
( 见源代码 ) 基本操作在顺序表上的实现
( 见源代码 )
四大基本操作 :
(1)    构造一个空的线性表
( 简单 )
(2)    顺序表的插入算法 .
算法分析 :
时间主要耗费在移动元素上 , 与问题的规模 (N) 和你插入元素的具体位置有关 , 即插入元素位置越靠近 , 位序 1, 消耗的时间也就越多 . 设在位序 i 插入元素的概率位 pi=1/(n+1), 移动元素的个数为 ,(n-i+1):
      那么在长度为 n 的顺序表中 , 插入一个元素 , 所需移动元素的期望值为 :
      E = ∑ P i*(n-i+1)     (i=1,2,3,..,n+1)
       =n/2;
平均移动表中的一半元素 . 时间复杂度 O( n )
(3)    顺序表的删除算法 .
算法分析 :
同上 , E = ∑ q i*(n-i)     (i=1,2,3,..,n+1) qi=1/n
        =(n-1)/2;
时间复杂度为 O (n);
(4)    定位算法 .
算法分析 :
基本操作是进行两个元素之间的比较 , 假设存在该元素为 a i( 1 ≤ i ≤ n), 则比较的次数为 i, 否则为 n, 所以算法时间复杂度为 O(n); 顺序存储结构的性能小结 :
优点 :
(1)    可以随机存取 , 顺序表中的数据元素 .
(2)    存储空间连续 , 不必要增加额外的存储空间 . 比如如果你以链式结构存储 , 那么你就不得不增加一个指针域 .
缺点 :
(1) 插入和删除一个元素 , 需要移动大量元素 , 耗费时间 .
(2) 初始化顺序表的时候 , 要预先分配一个最大空间 . 有时候会使存储空间得不到充分利用 .
(3) 容量难以扩充 .
posted @ 2006-06-15 17:25 liulang 阅读(1439) | 评论 (0)编辑 收藏