如何在 ASMX Web 服务中使用事务

本文关键字:事务 服务 Web ASMX | 更新日期: 2023-09-27 18:35:24

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

编码网络服务.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));
    }

但是现在的结果是"交易失败"。

我希望结果"事务强制"并插入到数据库完成。

如何在 ASMX Web 服务中使用事务

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

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

[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块中,因此不需要显式finally。一个using块相当于一个try/catch/finally