少年阿賓

          那些青春的歲月

            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 閱讀(412) | 評論 (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 閱讀(948) | 評論 (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 閱讀(416) | 評論 (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 閱讀(508) | 評論 (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 閱讀(487) | 評論 (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 閱讀(577) | 評論 (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 閱讀(2942) | 評論 (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 閱讀(463) | 評論 (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 閱讀(412) | 評論 (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 閱讀(505) | 評論 (0)編輯 收藏

          僅列出標題
          共50頁: First 上一頁 4 5 6 7 8 9 10 11 12 下一頁 Last 
          主站蜘蛛池模板: 长沙市| 西乌珠穆沁旗| 沙河市| 霞浦县| 卢龙县| 乐亭县| 广丰县| 鄂温| 磴口县| 石屏县| 合阳县| 和林格尔县| 聂拉木县| 博乐市| 阳城县| 潞城市| 顺昌县| 鸡西市| 抚松县| 黑龙江省| 香港| 丰原市| 沾益县| 铜川市| 习水县| 奉化市| 奇台县| 佛山市| 明溪县| 江华| 汝南县| 德安县| 若尔盖县| 司法| 施秉县| 伽师县| 乐亭县| 廊坊市| 明光市| 全州县| 彭州市|