不要在儲存過程中控制事務
MySQL技術內幕 InnoDB儲存引擎 344頁.
原來看過這段,總而言之,就是MySQL不要在儲存過程中控制事務.
當時沒有仔細看細節,只是記住了一個結論.
畢竟都21世紀了.還有用儲存過程的?
但是..#(×&%¥×&@……&……#@&
以如下過程為例.
連續呼叫兩次過程,會觸發主鍵衝突的異常.
最後的commit沒有執行,第二個過程的事務並未完成.
這時,需要上層呼叫的程式,進行事務的提交或者回滾.
當然,也可以定義一個Handler進行異常處理.
第一個過程執行成功,第二個過程觸發異常處理自動回滾
但是,上層的JAVA程式對於這一切,都透明瞭..
他後續的工作怎麼處理?
快取是否更新?分散式架構下,任務還繼續嗎?給客戶端返回什麼?
所以,過程和JAVA程式還得約定異常的型別.
這樣約定異常的常量,把異常處理,自己又實現了一遍.
MSSQL 可以自動回滾事務,並且會丟擲異常,上層JAVA開發可以捕獲這個異常.
但是MySQL還是做不到的.
所以事務控制最好由程式端完成.
JAVA程式呼叫過程之前,開啟事務,然後呼叫過程,根據過程的執行情況,提交或者回滾.
原來看過這段,總而言之,就是MySQL不要在儲存過程中控制事務.
當時沒有仔細看細節,只是記住了一個結論.
畢竟都21世紀了.還有用儲存過程的?
但是..#(×&%¥×&@……&……#@&
以如下過程為例.
- drop table nums;
- drop procedure pCreateNums;
- create table nums(id int not null primary key);
- delimiter $$
- create procedure pCreateNums(cnt int)
- begin
- -- declare exit handler for sqlexception rollback;
- start transaction;
- insert into nums(id) values(cnt+rand()*100);
- insert into nums(id) values(cnt);
- commit;
- end $$
- delimiter ;
- call pCreateNums(10);
- call pCreateNums(10);
連續呼叫兩次過程,會觸發主鍵衝突的異常.
最後的commit沒有執行,第二個過程的事務並未完成.
這時,需要上層呼叫的程式,進行事務的提交或者回滾.
當然,也可以定義一個Handler進行異常處理.
- drop table nums;
- drop procedure pCreateNums;
- create table nums(id int not null primary key);
- delimiter $$
- create procedure pCreateNums(cnt int)
- begin
- declare exit handler for sqlexception rollback;
- start transaction;
- insert into nums(id) values(cnt+rand()*100);
- insert into nums(id) values(cnt);
- commit;
- end $$
- delimiter ;
- call pCreateNums(10);
- call pCreateNums(10);
第一個過程執行成功,第二個過程觸發異常處理自動回滾
但是,上層的JAVA程式對於這一切,都透明瞭..
他後續的工作怎麼處理?
快取是否更新?分散式架構下,任務還繼續嗎?給客戶端返回什麼?
所以,過程和JAVA程式還得約定異常的型別.
- drop table nums;
- drop procedure pCreateNums;
- create table nums(id int not null primary key);
- delimiter $$
- create procedure pCreateNums(cnt int)
- begin
- declare exit handler for sqlexception begin rollback;select -1;end;
- start transaction;
- insert into nums(id) values(cnt+rand()*100);
- insert into nums(id) values(cnt);
- commit;
- select 1;
- end $$
- delimiter ;
這樣約定異常的常量,把異常處理,自己又實現了一遍.
MSSQL 可以自動回滾事務,並且會丟擲異常,上層JAVA開發可以捕獲這個異常.
但是MySQL還是做不到的.
所以事務控制最好由程式端完成.
- drop table nums;
- drop procedure pCreateNums;
- create table nums(id int not null primary key);
- delimiter $$
- create procedure pCreateNums(cnt int)
- begin
- start transaction;
- insert into nums(id) values(cnt+rand()*100);
- insert into nums(id) values(cnt);
- end $$
- delimiter ;
JAVA程式呼叫過程之前,開啟事務,然後呼叫過程,根據過程的執行情況,提交或者回滾.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-2112572/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 儲存過程WHERE條件不生效儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程
- jsp中呼叫儲存過程JS儲存過程
- 函式儲存過程併發控制-案例函式儲存過程
- 【MySQL】MySQL(三)儲存過程和函式、觸發器、事務MySql儲存過程函式觸發器
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- 儲存過程與儲存函式儲存過程儲存函式
- SQLSERVER儲存過程SQLServer儲存過程
- 呼叫儲存過程儲存過程
- mysql 儲存過程MySql儲存過程
- unidac儲存過程儲存過程
- firedac儲存過程儲存過程
- Oracle儲存過程Oracle儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- Oracle儲存過程乾貨(二):PLSQL控制語句Oracle儲存過程SQL
- MySQL儲存過程中如何使用ROLLBACKMySql儲存過程
- JdbcTemplate調儲存過程JDBC儲存過程
- 造數儲存過程儲存過程
- 儲存過程——遊標儲存過程
- 儲存過程 傳 datatable儲存過程
- JAVA儲存過程(轉)Java儲存過程
- MySQL之儲存過程MySql儲存過程
- oracle的儲存過程Oracle儲存過程
- MySQL---------儲存過程MySql儲存過程
- linux呼叫儲存過程Linux儲存過程
- Winform呼叫儲存過程ORM儲存過程
- mysql儲存過程整理MySql儲存過程
- Oracle儲存過程-1Oracle儲存過程
- 檢視、儲存過程以及許可權控制練習儲存過程
- 使用儲存過程(PL/SQL)向資料庫中儲存BLOB物件儲存過程SQL資料庫物件
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- mongo 儲存過程詳解Go儲存過程
- SQL 分頁儲存過程SQL儲存過程
- 原創:oracle 儲存過程Oracle儲存過程
- 資料庫儲存過程資料庫儲存過程
- mybatis儲存過程返回listMyBatis儲存過程
- Mysql 儲存過程的使用MySql儲存過程
- mysql如何呼叫儲存過程MySql儲存過程