如何在 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));
}
但是现在的结果是"交易失败"。
我希望结果"事务强制"并插入到数据库完成。
代码的主要问题是忽略了异常。永远不要忽略异常。他们通常会告诉你代码出了什么问题。
您的代码还有其他几个问题,我将使用以下更正后的代码进行解释:
[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();
//}
}
}
}
}
}
通常最好在其使用点附近声明变量。由于除了在 web 方法中之外没有使用这些变量,因此我将它们全部移到了里面。我把字符串留在外面不变。
SqlConnection
、SqlCommand
和SqlTransaction
都需要在using
块中,以确保它们使用的任何资源都将随着块的完成而清理,无论是否抛出异常。对于实现IDisposable
接口的类来说也是如此,当您在同一代码跨度中创建、使用它们并完成使用它们时。另一个使用块,但更重要的是,我使用参数作为最佳实践。不应通过字符串串联来构建 SQL 查询,因为它允许调用方(或用户)口述要执行的查询的文本。这可以防止"SQL注入攻击"。
另一个
using
块。SqlTransaction
由BeginTransaction
方法创建。这是代码中最严重的问题。永远不要忽略异常。至少,请务必将异常记录在以后可以阅读的位置。
对于此示例,我遵循了返回字符串的做法,但我在字符串末尾添加了完整的异常。不漂亮,但所有信息都会在那里。
由于
conn
位于using
块中,因此不需要显式finally
。一个using
块相当于一个try/catch/finally
。