網頁

2012年10月1日 星期一

以SqlTransaction搭配具名參數實作轉帳流程

一般而言,,簡略的轉帳流程大致可分為幾個部分:
1. 查詢帳戶餘額是否大於要轉帳的金額,如餘額足夠付款則進行下一個動作。
2. 轉出付款者所輸入的金額至收款者帳戶,付款者帳戶餘額 = 原始餘額扣除轉出金額。
3. 轉入付款者所輸入的金額至收款者帳戶,收款者帳戶餘額 = 原始餘額加上轉入金額。
4. 如上述動作皆完成,則通知付款者轉帳成功;
如未成功則不更動收(付)款者帳戶餘額,並通知付款者轉帳失敗。

簡而言之,即是將付款者帳戶餘額扣掉輸入之金額後再將收款者帳戶餘額加上輸入之金額。

而要如何利用SqlTransaction來做出轉帳功能呢?
其實很簡單,照著上述流程走就行了!
只是筆者建議作新增、修改、刪除皆使用具名參數輸入資料,以確保安全。

轉帳流程範例程式碼如下:


using.System.Data.SqlClient;//引用SqlClient以進行轉帳
using System.Data;//引用Data以進行餘額查詢
.
. 
.
.
//----------------------Button1_Click
 //宣告使用的物件
        SqlConnection connect = new SqlConnection
            ("server = localhost; uid = xxxx; pwd = xxxx; database = transaction;");
        SqlDataReader dr;
        //inquirecmd為查詢餘額,transoutcmd為轉帳出戶金額, transincmd為轉帳入戶金額;
        SqlCommand inquirecmd,transoutcmd, transincmd;
         //開啟連線

        connect.Open();
        //宣告交易物件並開始資料庫交易
        SqlTransaction tran = connect.BeginTransaction();
        try
        {
            
            //執行餘額查詢,並限制付款方帳戶餘額須大於轉出金額才可進行轉帳
            inquirecmd = new SqlCommand
            ("SELECT @payuser FROM account WHERE user = @payuser AND balance >= @money",
 connect);
            //定義餘額查詢中具名參數及給值
            inquirecmd.Parameters.Add("@payuser", SqlDbType.NVarChar).Value = payuserBox.Text;
            inquirecmd.Parameters.Add("@money", SqlDbType.NVarChar).Value = int.Parse(moneyBox.Text);
            inquirecmd.ExecuteNonQuery();
            //將查詢結果帶入dr
            dr = inquirecmd.ExecuteReader();
            //假如餘額大於轉出金額則進行轉帳,小於轉出金額則中斷轉帳流程並提醒使用者餘額不足
            if (dr.Read())
            {
                 dr.Close();
                //扣除付款方餘額,請注意connect後方加入了tran,表示此指令列為轉帳流程之一
                transoutcmd = new SqlCommand
                    ("UPDATE account SET balance = balance - @money WHERE user = @payuser", connect,
 tran);
                //增加付款方餘額,請注意connect後方加入了tran,表示此指令列為轉帳流程之一
                transincmd = new SqlCommand
                    ("UPDATE account SET balance = balance + @money WHERE user = @getuser", connect, 
tran);
                //定義付款方扣款指令中具名參數及給值
                transoutcmd.Parameters.Add("@money", SqlDbType.Int).Value = int.Parse(moneyBox.Text);
                transoutcmd.Parameters.Add("@payuser", SqlDbType.NVarChar).Value = payuserBox.Text;
                //定義收款方指令中具名參數及給值
                transincmd.Parameters.Add("@money", SqlDbType.Int).Value = int.Parse(moneyBox.Text);
                transincmd.Parameters.Add("@getuser", SqlDbType.NVarChar).Value = getuserBox.Text;
                //執行轉帳流程,如轉出與轉入流程皆完成則交易成功
                transoutcmd.ExecuteNonQuery();
                transincmd.ExecuteNonQuery();
                //交易成功,顯式交易成功訊息及交易金額
                tran.Commit();
                Response.Write("交易成功,交易金額為" + moneyBox.Text);
            }
            else
            {
                //查詢結果餘額不足,提醒消費者並且不進行轉帳流程
                throw new Exception("餘額不足");
            }
        }
        catch (Exception ex)
        {
            //交易失敗,將交易資料復原至交易開始時,並通知使用者交易失敗
            tran.Rollback();
            Response.Write("交易失敗,請確認輸入之帳戶是否正確");
        }

            connect.Close();


沒有留言:

張貼留言