JAVA程序對MYSQL數據庫加鎖實驗

如下實驗僅在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.任何能夠觸發事務提交的命令,均可以關閉共享鎖和排它鎖.

相關文章
相關標籤/搜索