我有一個名爲sales_observation_daily_summary的表,它是sales_observation_daily_summary_view的物化視圖。存儲過程名爲sync_daily_summary_view_with_table,它將刷新物化視圖,從功能上講,它的工作原理與我的想法完全相同,但是在同一連接上調用存儲過程兩次時(使用連接池時可能出現的情況)出現在我的Java集成測試中,但是我可以很容易地在MySQL Workbench上重現它,所以它不應該與JDBC或Spring或任何中間任何事情有關。MySQL存儲過程在第二次調用時出現「SELECT命令被拒絕給用戶'用戶'@'localhost'表'view_name'的同一連接失敗
call sync_daily_summary_view_with_table();
call sync_daily_summary_view_with_table();
在第一次調用時,它執行它應該執行的操作並正常返回。在第二個電話,我得到:
Error Code: 1142
SELECT command denied to user 'test'@'localhost' for table 'one_pg_someone_sales_observation_daily_summary_view'
one_pg_someone_sales_observation_daily_summary_view在sales_observation_daily_summary_view,這是在存儲過程中引用的參考。首先,存儲過程在第一次運行時並不反對,因此該錯誤消息毫無意義,其次,該用戶有足夠的權利在該視圖上進行選擇。
我不會讓所有的參與,因爲它是非常複雜的意見,但sales_observation_daily_summary_view被定義爲其他若干意見工會這樣的:
CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`localhost`
SQL SECURITY DEFINER
VIEW `sales_observation_daily_summary_view` AS
/* Specific Stage and Observer */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM one_pg_someone_sales_observation_daily_summary_view
UNION ALL /* All Stages */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM all_stages_someone_sales_observation_daily_summary_view
UNION ALL /* All Activities */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM all_activities_someone_sales_observation_daily_summary_view
UNION ALL /* All Observers */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM one_pg_everyone_sales_observation_daily_summary_view
UNION ALL /* Everyone over All Stages */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM all_stages_everyone_sales_observation_daily_summary_view
UNION ALL /* Everyone over All Activities */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM all_activities_everyone_sales_observation_daily_summary_view
UNION ALL /* Benchmark */
SELECT zone,
session_date,
session_year,
session_month,
session_week,
phenomenon_group_id,
phenomenon_group_name,
stage_id,
stage_name,
observer_id,
series_name,
benchmark_id,
session_count,
session_value,
benchmark_value
FROM benchmark_sales_observation_daily_summary_view
的存儲過程是這樣定義的:
DELIMITER $$
CREATE DEFINER=`test`@`localhost` PROCEDURE `sync_daily_summary_view_with_table`()
BEGIN
/* Update any values that may have changed */
UPDATE sales_observation_daily_summary tb,
sales_observation_daily_summary_view vw
SET tb.session_count = vw.session_count,
tb.session_value = vw.session_count,
tb.benchmark_value = vw.benchmark_value,
tb.series_name = vw.series_name
WHERE vw.zone = tb.zone
AND vw.session_date = tb.session_date
AND Coalesce(vw.phenomenon_group_id, 0) =
Coalesce(tb.phenomenon_group_id, 0)
AND Coalesce(vw.stage_id, 0) = Coalesce(tb.stage_id, 0)
AND Coalesce(vw.observer_id, 0) = Coalesce(tb.observer_id, 0)
AND Coalesce(vw.benchmark_id, 0) = Coalesce(tb.benchmark_id, 0)
AND (Coalesce(tb.session_count, -1) <> Coalesce(vw.session_count, -1)
OR Coalesce(tb.session_value, -1) <>
Coalesce(vw.session_value, -1)
OR Coalesce(tb.benchmark_value, -1) <>
Coalesce(vw.benchmark_value, -1)
OR tb.series_name <> vw.series_name);
END
我在本地開發框中使用5.1.56版本的日誌。
UPDATE 1 我也在Amazon RDS服務器版本5.1.57-log上重現了錯誤。
UPDATE 2 如果我定義存儲過程是SQL SECURITY INVOKER
並執行它作爲根,它工作正常。這不是一個可接受的解決方法,但它可能是某種線索。 (例如,它不是一個表鎖定問題。
更新3 涉及的表是InnoDB表,我不知道這是否是一個線索,但是當我添加了一個開始事務的開始和一個在提交最後,花了更長的時間才能完成,但隨後上了第二次調用同樣的錯誤。
UPDATE 4 我已經簡化了存儲過程,仍然重現的問題,它曾經有過的INSERT語句後跟通過更新語句。事實證明,更新語句足以重現錯誤,因此我從存儲過程ab中刪除了插入語句OVE。
你可以在另一臺服務器上重現它嗎? – Devart
是的,我編輯了我的描述以反映這一點。本地盒子上的5.1.56和Amazon RDS上的5.1.57都有這個問題。 – jhericks
你是唯一使用視圖/存儲過程的人嗎?這聽起來像是視圖中的一個表可以被鎖定。 – Mindfulgeek