少年阿宾

那些青春的岁月

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

#

【51CTO精选译文】G1垃圾回收器(简称G1 GC)是JDK 7中Java HotSpot VM新引入的垃圾回收器,Java SE 6 Update 14中已经包含了一个G1的体验版本(据51CTO之前的报导,在Java SE 6 u14于6月初登场时,原本Sun的声明是:G1垃圾回收器需要收费方能使用。然而之后不久,Sun表示这是一个误会,修改了原本的发布声明,并表示现在以及将来对G1的使用都是完全免费的),G1是设计用于替代HotSpot低延迟的并行标记/清除垃圾回收器(也叫做CMS)的。
Java 7 G1属性
G1是一个服务端垃圾回收器,有以下属性:
◆并行和并发性:G1利用了当今硬件中存在的并行性,当Java应用程序的线程被停止时,它使用所有可用的CPU(核心,硬件线程等)加速其停止,在停止过程中运行Java线程最小化整个堆栈。
◆代:和其他HotSpot GC一样,G1是一代,意味着它在处理新分配的对象(年轻代)和已经生存了一段时间的对象(年老代)时会不同,它主要集中于新对象上的垃圾回收活动,因为它们是最可能回收的,旧对象只是偶尔访问一下,对于大多数Java应用程序,代的垃圾回收对于替代方案具有重要优势。
◆压缩:和CMS不同,G1会随时间推移对堆栈进行压缩,压缩消除了潜在的碎片问题,确保长时间运行的操作流畅和一致。
◆可预测性:G1比CMS预测性更佳,这都是由于消除了碎片问题带来的好处,再也没有CMS中停止期间出现的负面影响,另外,G1有一个暂停预测模型,允许它满足(或很少超过)暂停时间目标。
Java 7 G1描述
和其它HotSpot GC相比,G1采用了一个非常不同的堆栈布局方法,在G1中,年轻代和年老代之间没有物理隔离,相反,它们之间有一个连续的堆栈,被分成大小一样的区域(region),年轻代可能是一套非连续的区域,年老代也一样,这就允许G1在年轻代和年老代之间灵活地移动资源。
G1中的回收是通过消除暂停发生的,在此期间,幸存者指的是回收集被转移到另一个区域,以便回收区域可以再生,消除暂停是并行的,所有可用的CPU都会参加,大多数消除暂停收集可用的年轻区域,和其它HotSpot GC中的年轻回收是一样的,在暂停期间偶尔也会选择年老区域回收,因为G1在年轻一代回收上还肩负了年老代的回收活动。
和CMS相同的是,G1会定期执行一个并发标记暂停,这个阶段的主要职责是识别哪一个年老区域的垃圾对象是最完整的,因为这些是最有效和最值得回收的,和CMS不同的是,G1不会执行并发清除暂停,相反,最有用的年老区域是通过并发标记暂停标识的,在随后的消除暂停期间进行回收。
使用G1
G1仍然被看做是试验品,可以使用下面两个参数开启它:
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC 
为了设置一个GC暂停时间目标,使用下面的参数:
-XX:MaxGCPauseMillis =50  (暂停时间目标50ms) 
使用G1时还可以指定时间间隔,当GC暂停持续时间没有上面给出的时间长时可以这么用:
-XX:GCPauseIntervalMillis =200  (暂停间隔目标200ms) 
注意上面两个选项表示的目标,没有承诺和保证,在某些情况下它们可能能够工作,GC不是总是能够执行它们。
另外,年轻代的大小可以明确指定影响消除暂停时间:
-XX:+G1YoungGenSize=512m (年轻代大小512M) 
G1也使用幸存空间(可能是非连续的区域),它们的大小可以使用一个常见的参数指定,如:
-XX:SurvivorRatio=6 
最后,为了运行G1充分发挥其潜力,尝试设置以下两个默认被禁用了的参数,因为它们可能会暴露一个罕见的竞争状态:
-XX:+G1ParallelRSetUpdatingEnabled  
 
-XX:+G1ParallelRSetScanningEnabled  
注意当设置了-XX:+PrintGCDetails后,G1比起其它HotSpot GC要啰嗦得多,因为它会打印每个GC线程的计时和其它有助于进行故障排除的信息,如果你想使GC日志更简单,请使用-verbosegc参数。
Java 7 G1最新进展
G1开发现在主要集中在遗留的可靠性问题和改善性能,同时也在逐步移除下面的限制:
◆G1不能完全支持JVM工具接口(JVM TI)或Java管理扩展(JMX),因此关于G1的监视和管理工具很可能不能正常工作;
◆G1不支持增量永久性代回收,如果一个应用程序产生了许多类转储,需要永久性代回收,这在完整GC期间是可以实现的;
◆从GC暂停时间来说,G1有时表现比CMS好有时比CMS差。
原文:Java HotSpot Garbage Collection
posted @ 2015-03-09 20:15 abin 阅读(393) | 评论 (0)编辑 收藏

centos端口转发神器:socat安装及使用
sudo nohup socat tcp-l:6666,reuseaddr,fork tcp:114.80.***.***:80 &

sudo nohup socat tcp-l:外部访问端口,reuseaddr,fork tcp:192.168.xxx.xxx:内部转发端口

Linux下Iptables端口转发功能的解决

将881请求发至10.10.2.00:881端口

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 881 -j DNAT --to-destination 10.10.2.200:881  

posted @ 2015-03-02 11:44 abin 阅读(933) | 评论 (0)编辑 收藏

package com.cp.common.aop;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class TimeHandler
  implements MethodInterceptor
{
  private static final Log log = LogFactory.getLog(TimeHandler.class);
  private int error;
  private int warn;
  private int info;
  public TimeHandler()
  {
    this.error = 200;
    this.warn = 100;
    this.info = 50;
  }
  public Object invoke(MethodInvocation methodInvocation)
    throws Throwable
  {
    long procTime = System.currentTimeMillis();
    try {
      Object result = methodInvocation.proceed();
     return result;
    }
    finally {
      procTime = System.currentTimeMillis() - procTime;
      String msg = "Process method " + methodInvocation.getMethod().getName() + " successful! Total time: " + procTime + " milliseconds!";
      if (procTime > this.error)
        if (log.isErrorEnabled()) log.error(msg);
      else if (procTime > this.warn)
        if (log.isWarnEnabled()) log.warn(msg);
      else if (procTime > this.info)
        if (log.isInfoEnabled()) log.info(msg);
      else if (log.isDebugEnabled()) log.debug(msg);
    }
  }
  public void setError(int error)
  {
    this.error = error;
  }
  public void setWarn(int warn)
  {
    this.warn = warn;
  }
  public void setInfo(int info)
  {
    this.info = info;
  }
}
/*
对于上面的代码需要说明的是下面两行代码:
  Object result = methodInvocation.proceed();
  return result;
整个程序的流程是这样的:
  1,先是执行在Object result = methodInvocation.proceed();前面的代码;
  2,接着执行Object result = methodInvocation.proceed();,它把执行控制权交给了interceptor stack(拦截器栈)内的下一个interceptor,如果没有了就交给真正的业务方法;
  3,然后执行return result;之前的代码;
  4,最后执行return result;,它把控制权交回它之上的interceptor,如果没有了就退出interceptor stack。
*/
posted @ 2015-02-25 17:36 abin 阅读(414) | 评论 (0)编辑 收藏

 HashMap is implemented as a hash table, and there is no ordering on keys or values.
TreeMap is implemented based on red-black tree structure, and it is ordered by the key.
LinkedHashMap preserves the insertion order
Hashtable is synchronized, in contrast to HashMap.
posted @ 2015-02-15 10:59 abin 阅读(492) | 评论 (0)编辑 收藏

方法一:
直接执行命令:
mysql> select count(1) from table   into outfile '/tmp/test.xls';
Query OK, 31 rows affected (0.00 sec)
在目录/tmp/下会产生文件test.xls
遇到的问题:
mysql> select count(1) from table   into outfile '/data/test.xls';
报错:
ERROR 1 (HY000): Can't create/write to file '/data/test.xls' (Errcode: 13)
可能原因:mysql没有向/data/下写的权限,没有深究
方法二:
查询都自动写入文件:
mysql> pager cat > /tmp/test.txt ;
PAGER set to 'cat > /tmp/test.txt'
之后的所有查询结果都自动写入/tmp/test.txt',并前后覆盖
mysql> select * from table ;
30 rows in set (0.59 sec)
在框口不再显示查询结果
以上参考:http://blog.163.com/cpu_driver/blog/static/117663448201111295420990/
方法三:
跳出mysql命令行
[root@SHNHDX63-146 ~]# mysql -h127.0.0.1 -uroot -pXXXX -P3306 -e"select * from table" > /tmp/test/txt
posted @ 2015-02-04 14:50 abin 阅读(469) | 评论 (1)编辑 收藏

select FQQ,FScoreCount from Tbl_User into outfile "/tmp/terminatedtest.txt" fields terminated by ",";



select * from test into outfile '/home/user/test.txt'

在linux(centos)下 ,启动了mysql 并给用户文件读写的权利
grant file on *.* to root@localhost;

在linux系统上,目录的权限全部是 rwxrwxrwx
chmod 777 ...
/home/user/test
drwxrwxrwx  4 root root  4096 Sep  3 18:42 home
drwxrwxrwx 10 mapuser mapuser 4096 Sep  4 03:41 user
drwxrwxrwx 5 mapuser mapuser 4096 Sep  3 17:57 test


在mysql下输入
select * from test into outfile '/home/user/test.txt'
出现错误信息:
ERROR 1 (HY000): Can't create/write to file '/home/user/test.txt' (Errcode: 13)
当时如果是tmp目录的话就不会有这个错误
select * from test into outfile '/tmp/test.txt'
Query OK, 0 rows test(0.00 sec)

难道只能是tmp目录吗?
有什么地方可以修改的吗?
后来吧home的所有者改成了mysql
drwxrwxrwx  5 mysql mysql  4096 Sep  4 10:08 home
select * from test into outfile '/home/test.txt'

ERROR 1 (HY000): Can't create/write to file '/home/test.txt' (Errcode: 13)
也是同样出错。

这个有什么办法可以写入home目录下面吗?或者其他什么目录,只要不是tmp目录,有人说先写入tmp目录,再cp到想要的
目录,这样做是可以,不过比较麻烦,文件比较大,2-3G呢,

修改mysql的配置能实现吗?还是修改文件的权限,这个是什么问题呢?


select * from test into outfile '/tmp/test.txt'
Query OK, 0 rows test(0.00 sec)

看一下产生的这个文件的owner 是谁。


[root@localhost /]# ls -l
drwxrwxrwx    4 root     root         4096  9月  4 21:03 home
drwxrwxrwt   10 root     root         4096  9月  4 21:03 tmp

[root@localhost /]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 27
Server version: 5.1.14-beta MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select user from user;
+--------+
| user   |
+--------+
| system |
| root   |
+--------+
2 rows in set (0.03 sec)

mysql> select user from user into outfile '/home/test.txt';
Query OK, 2 rows affected (0.02 sec)

[root@localhost home]# ls -l
-rw-rw-rw-    1 mysql    mysql          12  9月  4 21:12 test.txt

[root@localhost home]# cat /home/test.txt
system
root


select * from test into outfile '/home/test.txt'

ERROR 1 (HY000): Can't create/write to file '/home/test.txt' (Errcode: 13)
------------------------
从Errcode: 13来看是没权限
你执行上面语句时,是用什么用户执行的呢?检查下这个用户是否有权限吧

估计和权限没关系,因为已经是777了。

看看是不是selinux打开了,如果没什么特别需要的话,关了为好。

非root用户,在mysql下执行的select * from test into outfile '/home/user/test.txt'


select * from test into outfile '/home/user/test.txt'该语句产生的文件是
-rw-rw-rw-    1 mysql    mysql          12  9月  4 21:12 test.txt
mysql组的mysql用户的。

貌似和权限没什么关系,我用root用户登陆系统,执行mysql的语句,其结果还是一样,写入/home目录时
select * from test into outfile '/home/test.txt'
ERROR 1 (HY000): Can't create/write to file '/home/test.txt' (Errcode: 13)
还是有这个问题。
selinux会阻止其他程序写入操作??
具体怎么改变一下selinx的配置呢

我理清是什么问题了。
在red hat系列的linux中selinux对哪些daemon可以进行怎么样的操作是有限制的,mysql的select into outfile的命令是mysql的daemon来负责写文件操作的。写文件之前当然要具有写文件的权限。而selinux对这个权限做了限制。如果 selinux是关闭的吧,这个命令执行是没有问题的
mysql> select user from user into outfile '/home/test.txt';
Query OK, 2 rows affected (0.02 sec)
当时selinux开启时
selinux对mysql的守护进程mysqld进行了限制。
mysql> select user from user into outfile '/home/test.txt';
ERROR 1 (HY000): Can't create/write to file '/home/test.txt' (Errcode: 13)
出现了没有权限写的error。
解决方法,可以关闭selinux。
可以在/etc/selinux中找到config
root用户,
shell>vi /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
     enforcing - SELinux security policy is enforced.
     permissive - SELinux prints warnings instead of enforcing.
     disabled - SELinux is fully disabled.
SELINUX=enforcing

修改SELINUX=disabled关闭selinux就可以了,这个问题就可以解决了。
不过全部关闭SELINUX有带来一些安全问题。
当然也可以,单独给mysql的守护进程权限,
shell>getsebool -a可以查看当前的对系统一系列守护进程的权限情况。

lpd_disable_trans --> off
mail_read_content --> off
mailman_mail_disable_trans --> off
mdadm_disable_trans --> off
mozilla_read_content --> off
mysqld_disable_trans --> off
nagios_disable_trans --> off
named_disable_trans --> off
named_write_master_zones --> off
nfs_export_all_ro --> on
nfs_export_all_rw --> on
nfsd_disable_trans --> off
nmbd_disable_trans --> off
nrpe_disable_trans --> off

shell>setsebool -P mysqld_disable_trans=1
开启对mysql守护进程的权限,这样
mysql> select user from user into outfile '/home/test.txt';
写入到自定义的目录就没有问题了。
-P表示 是永久性设置,否则重启之后又恢复预设值。
getsebool setsebool命令在root用户下有权限。

除了对selinux的权限,当然首先要保证该目录拥有读写权限。


在ubuntu下 ,可以对AppArmor(/etc/apparmor.d/usr.sbin.mysqld) 修改,类似selinux。
添加/etc/squid/lists/eighties.txt w,类似。

posted @ 2015-02-04 14:31 abin 阅读(552) | 评论 (1)编辑 收藏

input.py : 代码如下:
import sys
one = sys.argv[1]
print one

执行控制台命令:
[root@root ~] python input.py mypython
结果为
[root@root ~]
mypython

posted @ 2015-02-03 21:37 abin 阅读(2929) | 评论 (0)编辑 收藏

并发问题可归纳为以下几类:

 

A.丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖(AB事务并发执行,A事务执行更新后,提交;B事务在A事务更新后,B事务结束前也做了对该行数据的更新操作,然后回滚,则两次更新操作都丢失了)。

B.
脏读:一个事务读到另一个事务未提交的更新数据(AB事务并发执行,B事务执行更新后,A事务查询B事务没有提交的数据,B事务回滚,则A事务得到的数据不是数据库中的真实数据。也就是脏数据,即和数据库中不一致的数据)。

C.不可重复读:一个事务读到另一个事务已提交的更新数据(AB事务并发执行,A事务查询数据,然后B事务更新该数据,A再次查询该数据时,发现该数据变化了)。

D.
覆盖更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据(即A事务更新数据,然后B事务更新该数据,A事务查询发现自己更新的数据变了)。

 

E.虚读(幻读):一个事务读到另一个事务已提交的新插入的数据(AB事务并发执行,A事务查询数据,B事务插入或者删除数据,A事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了)。

数据库系统提供了四种事务隔离级别供用户选择:

A.Serializable
(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新(事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行。)。

B.Repeatable Read
(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。

C.Read Commited
(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。

D.Read Uncommitted
(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

 

 

丢失更新

脏读

非重复读

覆盖更新

幻像读

未提交读

Y

Y

Y

Y

Y

已提交读

N

N

Y

Y

Y

可重复读

N

N

N

N

Y

串行化

N

N

N

N

N



 

隔离级别

 

数据库系统有四个隔离级别(大多数数据库默认级别为read commited)。对数据库使用何种隔离级别要审慎分析,因为

1. 维护一个最高的隔离级别虽然会防止数据的出错,但是却导致了并行度的损失,以及导致死锁出现的可能性增加。

2. 然而,降低隔离级别,却会引起一些难以发现的bug。

 

SERIALIZABLE(序列化)

 

添加范围锁(比如表锁,页锁等,关于range lock,我也没有很深入的研究),直到transaction A结束。以此阻止其它transaction B对此范围内的insert,update等操作。

 

幻读,脏读,不可重复读等问题都不会发生。

 

REPEATABLE READ(可重复读)

 

对于读出的记录,添加共享锁直到transaction A结束。其它transaction B对这个记录的试图修改会一直等待直到transaction A结束。

 

可能发生的问题:当执行一个范围查询时,可能会发生幻读。

 

READ COMMITTED(提交读)

 

在transaction A中读取数据时对记录添加共享锁,但读取结束立即释放。其它transaction B对这个记录的试图修改会一直等待直到A中的读取过程结束,而不需要整个transaction A的结束。所以,在transaction A的不同阶段对同一记录的读取结果可能是不同的。

 

可能发生的问题:不可重复读。

 

READ UNCOMMITTED(未提交读)

 

不添加共享锁。所以其它transaction B可以在transaction A对记录的读取过程中修改同一记录,可能会导致A读取的数据是一个被破坏的或者说不完整不正确的数据。

 

另外,在transaction A中可以读取到transaction B(未提交)中修改的数据。比如transaction B对R记录修改了,但未提交。此时,在transaction A中读取R记录,读出的是被B修改过的数据。

 

可能发生的问题:脏读。

 

 

问题

 

我们看到,当执行不同的隔离级别时,可能会发生各种各样不同的问题。下面对它们进行总结并举例说明。

 

幻读

 

幻读发生在当两个完全相同的查询执行时,第二次查询所返回的结果集跟第一个查询不相同。

 

发生的情况:没有范围锁。

 

例子:

 

事务1事务2
SELECT  * FROM users WHERE age BETWEEN 10 AND 30 


INSERT INTO users VALUES ( 3 , 'Bob' , 27 ); 
COMMIT;
SELECT * FROM users WHERE age BETWEEN 10 AND 30;

 

 

如何避免:实行序列化隔离模式,在任何一个低级别的隔离中都可能会发生。

 

不可重复读

在基于锁的并行控制方法中,如果在执行select时不添加读锁,就会发生不可重复读问题。

在多版本并行控制机制中,当一个遇到提交冲突的事务需要回退但却被释放时,会发生不可重复读问题。

 

事务1事务2
SELECT * FROM users WHERE id = 1; 


UPDATE users SET age = 21 WHERE id = 1 ; COMMIT; /* in multiversion concurrency*/    control, or lock-based READ COMMITTED * 
SELECT * FROM users WHERE id = 1; 


COMMIT; /* lock-based REPEATABLE READ */ 

 

在上面这个例子中,事务2提交成功,它所做的修改已经可见。然而,事务1已经读取了一个其它的值。在序列化和可重复读的隔离级别中,数据库管理系统会返回旧值,即在被事务2修改之前的值。在提交读和未提交读隔离级别下,可能会返回被更新的值,这就是“不可重复读”。

 

有两个策略可以防止这个问题的发生:

1. 推迟事务2的执行,直至事务1提交或者回退。这种策略在使用锁时应用。(悲观锁机制,比如用select for update为数据行加上一个排他锁)

2. 而在多版本并行控制中,事务2可以被先提交。而事务1,继续执行在旧版本的数据上。当事务1终于尝试提交时,数据库会检验它的结果是否和事务1、事务2顺序执行时一样。如果是,则事务1提交成功。如果不是,事务1会被回退。(乐观锁机制)

 

脏读

脏读发生在一个事务A读取了被另一个事务B修改,但是还未提交的数据。假如B回退,则事务A读取的是无效的数据。这跟不可重复读类似,但是第二个事务不需要执行提交。 

 

事务1事务2
SELECT * FROM users WHERE id = 1;


UPDATE users SET age = 21 WHERE id = 1 
SELECT FROM users WHERE id = 1;


COMMIT; /* lock-based DIRTY READ */ 
posted @ 2015-01-31 18:20 abin 阅读(445) | 评论 (2)编辑 收藏

ANSI/ISO  SQL的四个isolation level

SERIALIZABLE

这是最高层次isolation level,这个层次的isolation实现了串行化的效果,即:几个Transcation在执行时,其执行效果和某个串行序执行这几个Transaction的效果是一样的。使用Serializable层次的事务,其中的查询语句在每次都必须在同样的数据上执行,从而防止了phantom read,其实现机制是range lock。与下一个层次的不同之处在于range lock。

在基于锁的DBMS中,Serializable直到事务结束才释放select数据集上的读、写锁。而且select查询语句必须首先获得range-locks才能执行。在非锁并行的DBMS中,系统每当检测到write collision时,一次只有一个write能被写入。

range lock

Range lock记录Serializable Transaction所读取的key值范围,阻止其他在这个key值范围内的记录被插入到表中。Range lock位于Index上,记录一个起始Index和一个终止Index。在Range lock锁定的Index范围内,任何Update、Insert和Delete操作都是被禁止的,从而保证了Serializable中的操作每次都在同样的数据集上进行。

REPEATABLE READS

在基于锁的DBMS中,Repeatable Reads直到事务结束才释放select数据集上的读、写锁。但不会使用range lock,因此会产生Phantom Read。

READ COMMITTED

在基于锁的DBMS中,Read Committed直到事务结束才释放select数据集上的写锁,但读锁会在一个select完成后才被释放。和Repeatable Read一样,Read Committed不使用range lock,会产生Phantom read和Unrepeatable read。(注:这段主要参考wikipedia,我也搜索过Read Committed,基本都采用了这种说法。但我有一个疑问,既然write锁直到事务提交才释放,那么在这个阶段是不会发生update操作的,在一个事务中的多个读应该也不会产生不同的结果才对。望知之者指点一二,小弟不胜感激。)

READ UNCOMMITTED

这是Isolation Level的最底层,不仅会产生Phantom Read、Unrepeatable Read,还会有Dirty Read的风险。

Read phenomena

SQL 92标准将事务T1读写T2的操作分为三种,Phantom Read、Unrepeatable Read和Dirty Read         Users
idnameage
1Joe20
2Jill25

Dirty reads (Uncommitted Dependency)

事务T1在读取事务T2已经修改、但T2还未提交的数据时会发生Dirty Read。这个Isolation Level唯一能保证的是Update操作按顺序执行,即事务中前面的update一定比后面的update先执行。

下面的这个例子是一个典型的Dirty Read

Transaction 1Transaction 2
/* Query 1 */
SELECT age FROM users WHERE id = 1;
/* will read 20 */
 
 
/* Query 2 */
UPDATE users SET age = 21 WHERE id = 1;
/* No commit here */
/* Query 1 */
SELECT age FROM users WHERE id = 1;
/* will read 21 */
 
 
ROLLBACK; /* lock-based DIRTY READ */

Non-repeatable reads

在一个事务T1中,如果对同一条记录读取两次而值不一样,那么就发生了Non-repeatable read。

在基于锁的DBMS中,Non-repeatable read可能在未获得read lock时进行select操作,或在select操作刚结束就释放read lock时发生。在多版本并行控制的DBMS中,non-repeatable read可能在违背“受commit conflict影响的事务必须回滚“的原则时发生。

Transaction 1Transaction 2
/* Query 1 */ SELECT * FROM users WHERE id = 1; 
 
 
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrency    control, or lock-based READ COMMITTED */ 
/* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */

有两种方式来防止non-repeatable read。第一种方式用锁使T1和T2串行。另外一种方式是在多版本并行控制的DBMS中使用的。在这里,T2可以提交,而先于T2启动的T1则在自己的Snapshot(快照)里继续执行,在T1提交时,系统会检查其结果是否与T1、T2序执行的结果一样,如果一样,则T1提交,否则T1必须回滚并生成一个serialization failure。

Phantom reads

Phantom read是指在一个事务中,执行两个或多个同样的查询返回的结果集却不相同的现象。这种现象发生在没获得range lock即进行select... where....操作时,解决方法是使用range lock。

Transaction 1Transaction 2
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; 
 
 
/* Query 2 */ INSERT INTO users VALUES ( 3, 'Bob', 27 ); COMMIT; 
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; 
 

参考:

http://msdn.microsoft.com/en-us/library/ms191272.aspx
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

posted @ 2015-01-31 18:15 abin 阅读(393) | 评论 (0)编辑 收藏

import MySQLdb
import csv
try:
    conn=MySQLdb.connect(host='localhost',user='root',passwd='',db='abin',port=3306)
    cursor=conn.cursor()
    result = cursor.execute('select * from tabin')
    info=cursor.fetchmany(result)
    writer = csv.writer(file('your.csv','wb'))
    writer.writerow(['id','name','time'])
    for line in info:
        writer.writerow(line)
except MySQLdb.Error,e:
    print 'MySQLError is : ',e.args[0]
posted @ 2015-01-28 16:16 abin 阅读(491) | 评论 (0)编辑 收藏

仅列出标题
共50页: First 上一页 4 5 6 7 8 9 10 11 12 下一页 Last