如何在ASMX Web服务中使用Transaction?

时间:2013-10-15 17:26:42

标签: c# asp.net web-services transactions asmx

我开始在Web服务中使用Transaction。我使用C#并开始使用Transaction插入。 但我不插入数据库。

代码WebService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Data;

[WebService(Namespace = "example.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]

public class WebService : System.Web.Services.WebService 
{
    SqlConnection conn;
    SqlCommand comm1, comm2, comm3;
    SqlTransaction trans;
    SqlDataAdapter adapter1, adapter2;
    DataSet ds1, ds2;
    string constring = "Database=transaction;server=localhost;user=sa;password=toon2255";

    [WebMethod(Description = "Transaction")]
    public string transaction(int userid, int amount)
    {
        conn = new SqlConnection(constring);
        conn.Open();
        comm2 = new SqlCommand("INSERT INTO moneytrans VALUES('" + userid + "','" + amount + "')");
        trans = conn.BeginTransaction();
        comm2.Transaction = trans;
        try
        {
            comm2.ExecuteNonQuery();
            trans.Commit();
            return "Transaction Complted. ";
        }
        catch (Exception)
        {
            trans.Rollback();
            return "Transaction Failed..";
        }
        finally
        {
            conn.Close();
        }
    }
}

代码Default.aspx.cx(网站)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

protected void btnok_Click(object sender, EventArgs e)
    {
        WSLogin.WebService obj = new WSLogin.WebService();
        lblmsg.Text = obj.transaction(Convert.ToInt32(txtuserid.Text), Convert.ToInt32(txtamount.Text));
    }
  

但结果现在“交易失败......”

     

我想要结果“交易强制”并插入数据库完成。

1 个答案:

答案 0 :(得分:0)

您的代码的主要问题是您忽略了异常。不要永远忽略异常。他们通常会告诉你代码有什么问题。

您的代码还有其他一些问题,我将使用以下更正的代码进行解释:

[WebService(Namespace = "example.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService : System.Web.Services.WebService
{
    // 1
    const string constring = "Database=transaction;server=localhost;user=sa;password=toon2255";

    [WebMethod(Description = "Transaction")]
    public string transaction(int userid, int amount)
    {
        // 2
        using (SqlConnection conn = new SqlConnection(constring))
        {
            conn.Open();
            // 3
            using (SqlCommand comm2 = new SqlCommand("INSERT INTO moneytrans VALUES(@userid,@amount)"))
            {
                comm2.Parameters.AddWithValue("@userid", userid);
                comm2.Parameters.AddWithValue("@amount", amount);

                // 4
                using (SqlTransaction trans = conn.BeginTransaction())
                {
                    comm2.Transaction = trans;
                    try
                    {
                        comm2.ExecuteNonQuery();
                        trans.Commit();
                        return "Transaction Completed. ";
                    }
                    // 5
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        // 6
                        return string.Format("Transaction Failed: {0}", ex);
                    }
                    // 7
                    //finally Not needed because of using block
                    //{
                    //    conn.Close();
                    //}
                }
            }
        }
    }
}
  1. 通常最好在其使用点附近声明变量。由于除了web方法之外没有使用这些变量,我将它们都移到了里面。我把弦留在了外面。

  2. SqlConnectionSqlCommandSqlTransaction都需要位于using块中,以确保他们使用的所有资源都会被清除无论是否抛出异常,块都已完成。对于实现IDisposable接口的类,在创建它们时使用它们,并在相同的代码范围内完成所有这些操作时,都是如此。

  3. 另一个使用块,但更重要的是,我使用参数作为最佳实践。您不应该通过字符串连接来构建SQL查询,因为它允许您的调用者(或您的用户)指定您将要执行的查询的文本。这可以防止“SQL注入攻击”。

  4. 另一个using块。 SqlTransactionBeginTransaction方法创建。

  5. 这是您的代码最严重的问题。不要永远忽略异常。至少,请务必将异常记录在以后可以阅读的地方。

  6. 对于这个例子,我遵循了返回字符串的做法,但我在字符串末尾添加了完整的异常。不漂亮,但所有信息都会在那里。

  7. 由于conn位于using块中,因此不需要显式finallyusing块相当于try/catch/finally