使用Lock tables后,在鎖定期間需要在其他線程使用其他別的未鎖定表,需要慎用鎖定,可能讀寫失敗等奇怪現象
參考:https://www.cnblogs.com/mqxs/p/3461928.html
写锁定:LOCK TABLES lrcolumnsdesc WRITE;
写锁,锁定之后,只有当前线程只可以對lrcolumnsdesc进行读操作和写操作,其他线程對對products读操作和写操作均被堵塞.....
如果當前線程需對其他的表的讀寫,也要加入鎖否則報錯,Table 'lucht05' was not locked with LOCK TABLES
其他線程對lrcolumnsdesc的上讀寫鎖都被阻塞
LOCK TABLES lrcolumnsdesc WRITE
SELECT * FROM lrcolumnsdesc --可查詢
SELECT * FROM lucht05 --報異常 lucht05 未加鎖
UNLOCK TABLES
LOCK TABLES lrcolumnsdesc WRITE,lucht05 WRITE
SELECT * FROM lrcolumnsdesc --可查詢
SELECT * FROM lucht05 --可查詢
UNLOCK TABLES
读锁定:LOCK TABLES lrcolumnsdesc READ;
读锁,锁定之后,无论是当前线程还是其他线程均只能读操作,写操作全部被堵塞....
如果當前線程需對其他的表的讀寫,也要加入鎖否則報錯,Table 'lucht05' was not locked with LOCK TABLES
其他線程可以同時對lrcolumnsdesc的上讀鎖
寫鎖只能一個線程上其他線程讀寫鎖都被堵塞
讀鎖可以在多個線程同時上
解锁:UNLOCK TABLES;
解鎖只解鎖當前線程的鎖,
以下再innodb下測試,發現存在鎖不住的情況 ,表中uid連續但是存在uid的範圍差和DT的數量不一致
參考:https://www.linuxidc.com/Linux/2017-06/144705.htm
LOCK TABLES 隱含提交事務,開始事務(START TRANSACTION)隱含UNLOCK TABLES 需要將AUTOCOMMIT=0
SET AUTOCOMMIT=0;設置后,以下代碼執行依然存在沒有鎖住情況
設置全局的后鎖有效
SHOW GLOBAL VARIABLES LIKE 'autocommit';
SET GLOBAL AUTOCOMMIT=0;//這樣設定后,可能會導致在鎖定期間對其他操作未鎖定的表的讀寫失敗
SQLHelper conn = new SQLHelper();
using (conn)
{
if (conn.OpenConnection())
{
//獲取任務單號的的表名
DataTable Dtemp = conn.OpenDataTable("select t_name from lrtablefilter where task_no='" + TaskNo + "'", CommandType.Text);
if (Dtemp.Rows.Count > 0)
{
string tableName = Dtemp.Rows[0]["t_name"].ToString();
try
{
conn.ExecuteSQL("LOCK TABLES " + tableName + " WRITE");//其他線程上會被堵塞
conn.BeginTrans();
//獲取執行前最大uid
Dtemp = conn.OpenDataTable("select ifnull(max(uid),0) from " + tableName, CommandType.Text);
if (Dtemp.Rows.Count > 0)
{
result = Dtemp.Rows[0][0].ToString();
}
MultInsert(conn, DT, tableName, "from_sit", SitNo);
//獲取執行后最大uid
Dtemp = conn.OpenDataTable("select ifnull(max(uid),0) from " + tableName, CommandType.Text);
if (Dtemp.Rows.Count > 0)
{
result += "," + Dtemp.Rows[0][0].ToString();
}
conn.Commit();
conn.ExecuteSQL("UNLOCK TABLES");//只解鎖當前線程的鎖
}
catch (Exception ex)
{
conn.Rollback();
conn.ExecuteSQL("UNLOCK TABLES");//只解鎖當前線程的鎖,釋放鎖隱含提交事務,不能放在回滾前面
throw ex;
}
}
Dtemp.Dispose();
Dtemp = null;
}
}