如下實驗僅在MySQL 5.0.45作的實驗.java
方法1:用mysql命令鎖住表.mysql
public void test() { String sql = "lock tables aa1 write"; // 或String sql = "lock tables aa1 read"; // 若是想鎖多個表 lock tables aa1 read ,aa2 write , ..... String sql1 = "select * from aa1 "; String sql2 = "unlock tables"; try { this.pstmt = conn.prepareStatement(sql); this.pstmt1 = conn.prepareStatement(sql1); this.pstmt2 = conn.prepareStatement(sql2); pstmt.executeQuery(); pstmt1.executeQuery(); pstmt2.executeQuery(); } catch (Exception e) { System.out.println("異常" + e.getMessage()); } }
1、對於read lock 和 write lock官方說明:
1.若是一個線程得到一個表的READ鎖定,該線程(和全部其它線程)只能從該表中讀取。
若是一個線程得到一個表的WRITE鎖定,只有保持鎖定的線程能夠對錶進行寫入。
其它的線程被阻止,直到鎖定被釋放時爲止。算法
2.當您使用LOCK TABLES時,您必須鎖定您打算在查詢中使用的全部的表。
雖然使用LOCKTABLES語句得到的鎖定仍然有效,可是您不能訪問沒有被此語句鎖定的任何的表。
同時,您不能在一次查詢中屢次使用一個已鎖定的表——使用別名代替,
在此狀況下,您必須分別得到對每一個別名的鎖定。sql
2、對與read lock 和 write lock我的說明:
1.read lock 和 write lock 是線程級(表級別).
2.在同一個會話中加了read lock鎖. 只能對這個表進行讀操做.對這個表之外的任何表都沒法進行增、刪、改、查的操做.
可是在不一樣會話中,只能對加了read lock的表進行讀操做.但能夠對read lock之外的表進行增、刪、改、查的操做.
3.在同一個會話中加了write lock鎖.只能對這個表進行讀、寫操做.對這個表之外的任何表都沒法進行增、刪、改、查的操做.
可是在不一樣會話中,沒法對加了write lock的表進行讀、寫操做.但能夠對write lock之外的表進行增、刪、改、查的操做.
4.若是表中使用了別名.(SELECT * FROM aa1 AS byname_table)
在對aa1加鎖時,必須把別名加上去(lock tables aa1 as byname_table read)
在同一個會話中.必須使用別名進行查詢.
在不一樣的會話中.能夠不須要使用別名進行查詢.
5.在多個會話中能夠對同一個表進行lock read操做.但不能在多個會話中對同一個表進行lock write操做(這些鎖將等待已鎖的表釋放自身的線程鎖)
若是多個會話對同一個表進行lock read操做.那麼在這些會話中,也只能對以鎖的表進行讀操做.
6.若是要你鎖住了一個表,須要嵌套查詢.你必須使用別名,而且,要鎖定別名.
例如.lock table aa1 read ,aa1 as byname_table read;
select * from aa1 where id in (select * from aa1 as xx where id=2);
7.解鎖必須用unlock tables;this
另:
在Java程序中,要想解鎖,須要調用 unlock tables來解鎖.
若是沒有調用unlock tables.
關閉connection 、程序結束 、調用GC 都能解鎖. .net
方法2:用記錄鎖鎖表. 線程
public void test() { String sql = "select * from aa1 for update"; // select * from aa1 lock in share mode; try { conn.setAutoCommit(false); this.pstmt = conn.prepareStatement(sql); pstmt.executeQuery(); } catch (Exception e) { System.out.println("異常" + e.getMessage()); } }
1.for update 與 lock in share mode 屬於行級鎖和頁級鎖code
2.for update 排它鎖,lock in share mode 共享鎖索引
3.對於記錄鎖.必須開啓事務.事務
4.行級鎖定事實上是索引記錄的鎖定.只要是用索引掃描的行(或沒索引全表掃描的行),都將被鎖住.
5.在不一樣的隔離級別下還會使用next-key locking算法.即所掃描的行之間的「間隙」也會也鎖住(在Repeatable read和Serializable隔離級別下有間隙鎖).
6.在mysql中共享鎖的含義是:在被共享鎖鎖住的行,即便內容被修改且並無提交.在另外一個會話中依然看到最新修改的信息.
在同一會話中加上了共享鎖.能夠對這個表以及這個表之外的全部表進行增、刪、改、查的操做.
在不一樣的會話中.能夠查到共享鎖鎖住行的最新消息.可是在Read Uncommitted隔離級別下不能對鎖住的表進行刪,
改操做.(須要等待鎖釋放才能操做...)
在Read Committed隔離級別下不能對鎖住的表進行刪,改操做.(須要等待鎖釋放才能操做...)
在Repeatable read隔離級別下不能對鎖住行進行增、刪、改操做.(須要等待鎖釋放才能操做...)
在Serializable隔離級別下不能對鎖住行進行增、刪、改操做. (須要等待鎖釋放才能操做...)
7.在mysql中排他鎖的含義是:在被排它鎖鎖住的行,內容修改並沒提交,在另外一個會話中不會看到最新修改的信息。
在不一樣的會話中.能夠查到共享鎖鎖住行的最新消息.可是Read Uncommitted隔離級別下不能對鎖住的表進行刪,
改操做.(須要等待鎖釋放才能操做...)
在Read Committed隔離級別下不能對鎖住的表進行刪,改操做.(須要等待鎖釋放才能操做...)
在Repeatable read隔離級別下不能對鎖住行進行增、刪、改操做.(須要等待鎖釋放才能操做...)
在Serializable隔離級別下不能對鎖住行進行增、刪、改操做. (須要等待鎖釋放才能操做...)
8.在同一個會話中的能夠疊加多個共享鎖和排他鎖.在多個會話中,須要等待鎖的釋放.
9.SQL中的update 與 for update是同樣的原理.
10.等待超時的參數設置:innodb_lock_wait_timeout=50 (單位秒).
11.任何能夠觸發事務提交的命令,均可以關閉共享鎖和排它鎖.