MySQL触发器主体不尊重AUTOCOMMIT
选项并始终在事务中运行?
我只有AFTER UPDATE
触发器设置一些计数器(例如标志更改将减少旧标志的计数器并增加新标志)并且有两个服务器具有相对较高的负载变化标志所有时间......有时它会陷入僵局:)
我已经设置了这两个表:
test (
id INT NOT NULL AUTO_INCREMENT,
data TEXT DEFAULT NULL,
PRIMARY KEY (id)
)
test2 (
id INT NOT NULL AUTO_INCREMENT,
val INT DEFAULT 0,
PRIMARY KEY (id)
)
插入一些虚拟数据:
INSERT INTO test (data) VALUES (RAND());
INSERT INTO test2 (id, val) VALUES
(1, 0),
(2, 0);
创建模拟数据计算的触发器(故意让我有时间运行第二次查询)并对test2
表中的数据进行虚拟更改:
DELIMITER $$
CREATE TRIGGER `test_AUPD` AFTER UPDATE ON `test` FOR EACH ROW
BEGIN
UPDATE test2
SET val = val + 1
WHERE id = 1;
SELECT SLEEP(30) INTO @void;
UPDATE test2
SET val = val - 1
WHERE id = 2;
END $$
当然:
SHOW VARIABLES LIKE 'autocommit';
-- autocommit, ON
我打电话的时候:
UPDATE test SET data = RAND();
在两个连接中,第一次连接需要30秒才能完成更新,但第二次连接需要大约55秒。
这种行为记录在哪里(我花了几个小时挖掘InnoDB事务锁等等,但没有运气)? 我想这是打开复制时的合理行为。
同步触发更新同一个表中的计数器的正确方法是什么? OR 如何处理这种情况?
答案 0 :(得分:0)
调试此方法的好方法似乎是从INFORMATION_SCHEMA
选择锁和交易信息:
SELECT
PS.id AS conneciton_id, PS.HOST AS host, PS.INFO AS query_full, INNOLOCK.lock_id,
INNOLOCK.lock_mode, INNOLOCK.lock_type, INNOLOCK.lock_table, INNOLOCK.lock_rec,
INNOTRX.trx_query, INNOTRX.trx_state, INNOTRX.trx_requested_lock_id
FROM INFORMATION_SCHEMA.INNODB_LOCKS AS INNOLOCK
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS INNOTRX
ON INNOLOCK.lock_trx_id = INNOTRX.trx_id
INNER JOIN INFORMATION_SCHEMA.PROCESSLIST AS PS ON PS.ID = INNOTRX.trx_mysql_thread_id;
这将获取这样的数据:
+-----------------------++-------------------------------+-----------------------------+
| connection_id || ***** | ***** |
| host || *****:***** | *****:***** |
| query_full || UPDATE test SET data = RAND() | SELECT SLEEP(30) INTO @void |
| lock_id || 1234567890:12345678:2:3 | 0124567890:01234567:1:2 |
| lock_mode || X | X |
| lock_type || RECORD | RECORD |
| lock_table || `test` | `test` |
| lock_rec || 2 | 2 |
| trx_query || UPDATE test SET data = RAND() | SELECT SLEEP(30) INTO @void |
| trx_state || LOCK WAIT | RUNNING |
| trx_requested_lock_id || 0124567890:01234567:1:2 | |
+-----------------------++-------------------------------+-----------------------------+
立即告诉您第一列中显示的查询正在等待锁0124567890:01234567:1:2
,而0124567890:01234567:1:2
中的锁定SELECT SLEEP(30)
的交易现在正在等待<asp:Panel ID="SearchPanel" runat="server">
<%--put all the controls here--%>
</asp:Panel>
。