Distributed implicit transaction based on TransactionScope class

Source: Internet
Author: User

System. in addition to the explicit Programming Model Based on the Transaction class mentioned in the previous section, the Transactions namespace also provides an implicit programming model using the TransactionScope class, which is more convenient and simple than the display programming model, it is also a recommended programming model in MSDN.

Next, we implement the previous bank transfer routine Based on the TransactionScope class.

Sample Code:

(1) SqlHelper. cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using MySql.Data.MySqlClient;
using System.Transactions;
using System.Data;
 
Namespace Transaction Processing
{
    public class SqlHelper
    {
        public static string GetConnection()
        {
            string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            return connStr;
        }
 
        public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters)
        {
            int result = -1;
            using (MySqlConnection conn = new MySqlConnection(GetConnection()))
            {
                conn.Open();
                
                using (MySqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(parameters);
                    result = cmd.ExecuteNonQuery();
                }
            }
            return result;
        }
 
        public static DataTable ExecuteDataTable(string sql, params MySqlParameter[] parameters)
        {
            using (MySqlConnection conn = new MySqlConnection(GetConnection()))
            {
                using (MySqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(parameters);
                    using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
                    {
                        using (DataSet ds = new DataSet())
                        {
                            da.Fill(ds);
                            return ds.Tables[0];
                        }
                    }
                }
            }
        }
    }
 
}

(2) Bankaccountn. cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MySql.Data.MySqlClient;
using System.Data;
using System.Transactions;
 
Namespace Transaction Processing
{
    public class Bankaccountn
    {
        public Bankaccountn(string bankaccountnId)
        {
            string sql = @"SELECT * FROM Bankaccountn WHERE BankaccountnId=@BankaccountnId;";
            DataTable dt = SqlHelper.ExecuteDataTable(sql, new MySqlParameter("@BankaccountnId", bankaccountnId));
            if (dt.Rows.Count <= 0)
            {
Throw new Exception ("the account does not exist! ");
            }
            else if (dt.Rows.Count > 1)
            {
Throw new Exception ("Exception message: an account with duplicate names exists! ");
            }
            else
            {
                this.bankaccountnId = dt.Rows[0]["BankaccountnId"] as string;
                this.UserName = dt.Rows[0]["UserName"] as string;
                this.Balance = Convert.ToDecimal(dt.Rows[0]["Balance"]);
            } 
        }
 
        private string bankaccountnId;
        public string UserName
        { 
            get; 
            private set; 
        }
        public decimal Balance
        {
            get;
            private set;
        }
        
        protected int Update()
        {
            string sql = @"UPDATE bankaccountn SET UserName = @UserName,Balance = @Balance 
                           WHERE BankaccountnId= @BankaccountnId;";
            return SqlHelper.ExecuteNonQuery(sql, new MySqlParameter("@BankaccountnId", this.bankaccountnId), new MySqlParameter("@UserName", this.UserName), new MySqlParameter("@Balance", this.Balance));
 
        }
        public void Epend( decimal money)
        {
            this.Balance -= money;
            this.Update();
        }
        public void Income(decimal money)
        {
            this.Balance += money;
            this.Update();
            
        }
        public bool HiddenTransferOfAccount(string incomeBankaccountnId, decimal money)
        {
            bool result = true;
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);
IncomeBankaccountn. Income (money); // The receiving account is recorded.
This. Epend (money); // payment account expenditure
                    scope.Complete();
                }
                catch (Exception ex)
                {
// Code for recording exception information
                    result = false;
                }
            }
            return result;
        }
    }
    
}

(3) test code

Bankaccountn one = new Bankaccountn("6666660123456789");
if (one.HiddenTransferOfAccount("6666669876543210", 200M))
{
Response. Write ("<script> alert ('transfer successful ') </script> ");
}
else
{
Response. Write ("<script> alert ('transfer failed') </script> ");
}

Code Analysis:

After TransactionScope is used, the transaction manager will pre-execute the code until the Complete (). If there is no error in the process, the transaction manager will be notified to submit the code. if the error is not reported, ensures the consistency of the entire execution process.

Note the following when using an implicit programming model:

1) ensure that the full registration of the resources involved in the transaction (such as the opening of the connection) is placed after the TransactionScope instantiates the object and before the Complete () method is called.

2) do not eat the exception from the TransactionScope Instantiation to the code that calls the Complete () method.

 
 
using (TransactionScope scope = new TransactionScope())
{
    try
    {
// Make sure that all resources involved in the transaction are registered at this location (such as opening a connection)
         Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);
IncomeBankaccountn. Income (money); // The receiving account is recorded.
This. Epend (money); // payment account expenditure
         scope.Complete();
    }
    catch (Exception ex)
    {
// Capture exceptions at this location
          result = false;
    }
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.