使用SQL SERVER存儲過程實現銀行轉賬業務

在銀行金融系統中,我們常常都要實現銀行轉賬這樣的業務操作,而這種金融系統併發性相當高,需要考慮的如何提高性能和保證安全性等相關的問題。使用存儲過程來實現銀行轉賬是一個很好的選擇。

SQL SERVER數據庫中的存儲過程相對於應用程序中來操作Transact-SQL語言的優缺點:

優點:

1.              存儲過程已在服務器註冊,預編譯,存儲過程預先編譯好放在數據庫內,減少編譯語句所花的時間

2.              存儲過程可以用於減少網絡通信流量,存儲過程代碼直接存儲於數據庫中,執行的時候只需要應用程序傳遞參數即可,而不需要整段的T-SQL代碼傳遞到數據庫中。

3.              重用性高,一段存儲過程,可以在應用程序中不同的位置來調用。

4.              可維護性高,把整個業務的操作封裝在一起,有利於以後做代碼的替換操作,而應用程序會在日後不斷的維護中,會導致TrancSQL過程代碼會變得越來越複雜,同時,更新存儲過程通常比更新應用程序簡單的多,更新應該程序需要編譯,部署。

5.              使用緩存改善性能,編譯好的存儲過程直接進入SQL SERVER的緩存中,使得下次執行的時候,能馬上調用。而在SQL SERVER 2005中,執行計劃已針對所有 T-SQL 批處理進行了緩存,效率和存儲過程差不多了。

6.              強制使用數據庫中的安全認證機制,使得應用程序的安全性提高:

a)         對存儲過程向特定用戶授權,也可以提供對特定數據的訪問。

b)        增強代碼安全,通過傳遞參數的方式,能有效防止 SQL注入。

缺點:

1.         可移植性差

a)         由於存儲過程將應用程序綁定到 SQL Server,因此使用存儲過程封裝業務邏輯將限制應用程序的可移植性。

b)        如果應用程序的可移植性在您的環境中非常重要,則將業務邏輯封裝在不特定於 RDBMS 的中間層中可能是一個更佳的選擇。

2.         增加數據庫服務器的負載

3.         舊版本的SQL SERVER的編程SQL語句功能較差,SQL SERVER 2005有所改善

4.         調試過程不如應用程序方便

 

下面我們來看看如何來使用SQL SERVER 2005的存儲過程實現銀行轉賬這樣的業務操作:

 

1.       準備工作:先創建一個account銀行賬戶表,腳本如下:

create table account(

       id int identity(1,1) primary key,

       cardno char(20),

       money numeric(18,2)

)

 

insert into account values('01',1000.0)

insert into account values('02',1000.0)
 

 

 

 

2.       實現方案1:

不考慮任何的條件,簡單實現兩個賬戶之間的轉賬操作。

參數:

@out_cardno:轉出賬戶

@in_cardno: 轉入賬戶

@money:   轉賬金額

 

CREATE PROCEDURE sp_transfer_money1

       @out_cardno char(20),

       @in_cardno char(20),

       @money numeric(18,2)

AS

BEGIN

       update account set money = money-@money where cardno=@out_cardno

       update account set money = money+@money where cardno=@in_cardno      

       PRINT '轉賬成功.'

END

 

-- 執行上面的存儲過程

EXEC sp_transfer_money1 '01','02',1200.0
 

 

出現問題:

       轉出賬戶”01”的只有1000塊,但是卻能夠成功的轉1200塊,這樣的做法是不可思議的。

 

 

3.       實現方案2:

加入對轉出賬戶的餘額判斷:

CREATE PROCEDURE sp_transfer_money2

       @out_cardno char(20),

       @in_cardno char(20),

       @money numeric(18,2)

AS

BEGIN

       DECLARE @remain numeric(18,2)

       select @remain=money from account where cardno=@out_cardno

       IF @remain>=@money

       BEGIN

              update account set money = money-@money where cardno=@out_cardno

              update account set money = money+@money where cardno=@in_cardno      

              PRINT '轉賬成功.'

       END

       ELSE

       BEGIN

              PRINT '餘額不足.'

       END

END

 

EXEC sp_transfer_money2 '01','02',1000.0
 

 

出現問題:

1.       存儲過程的參數從外部出入,但是不能確定參數的合法性,一旦參數出現問題,執行存儲過程就可能發生錯誤,導致部分業務代碼執行不成功,發生數據不一致的問題。

2.       缺少事務控制的管理

 

4.       實現方案3:

 

CREATE PROCEDURE sp_transfer_money3

       @out_cardno char(20),

       @in_cardno char(20),

       @money numeric(18,2)

as

BEGIN

       DECLARE @remain numeric(18,2)

       select @remain=money from account where cardno=@out_cardno

       if @remain>@money

       BEGIN

              BEGIN TRANSACTION T1

                     update account set money = money-@money where cardno=@out_cardno

                     update account set money = money+@money where cardno=@in_cardno                                PRINT '轉賬成功.'

                     if @remain>@money

                     begin

                            rollback transaction

                     end

              COMMIT TRANSACTION T1

       END

       ELSE

       BEGIN

              PRINT '餘額不足.'

       END

END

 

EXEC sp_transfer_money3 '01','02',100.0
 

 

現實生活中的金融業務是相當複雜的,上面的幾個方案只是模擬了最基本的情況,譬如,跨行之間的轉賬,同行不同區的轉賬這些都是具體的業務需求。要把這些業務都使用存儲過程來實現的話,對我們的數據庫開發人員來說,要求就更高了。

 

發佈了33 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章