Mysql 鎖表與解鎖

使用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;
                    }
                }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值