如何将这些调用放入 SqlTransaction 中?
我有一个类,其中包含 ASP.NET 4.0 应用程序的所有数据访问代码。该类中有两个方法将数据插入数据库。我想在 SqlTransaction 中登记这些插入,并在其中一个插入失败时回滚事务。然而,由于我的编码方式,我不确定如何做到这一点。这是我的数据访问代码:
public class DBUtil
{
private static readonly string _connectionString;
static DBUtil()
{
_connectionString = WebConfigurationManager.ConnectionStrings["MooDB"].ConnectionString;
if (string.IsNullOrEmpty(_connectionString))
throw new Exception("Connection string not configured in Web.Config file");
}
public int InsertTrade(
string symbol,
string tradeSetupId,
int tradeTypeId,
decimal lotsPerUnit,
string chartTimeFrame,
decimal pctAccountRisked,
int? tradeGrade = null,
int? executionGrade = null,
int? MFEPips = null,
int? MAEPips = null
)
{
SqlCommand cmd = new SqlCommand("usp_InsertTrade");
// required parameters
cmd.Parameters.AddWithValue("@symbol", symbol);
cmd.Parameters.AddWithValue("@tradeSetupId", tradeSetupId);
cmd.Parameters.AddWithValue("@tradeTypeId", tradeTypeId);
cmd.Parameters.AddWithValue("@lotsPerUnit", lotsPerUnit);
cmd.Parameters.AddWithValue("@chartTimeFrame", chartTimeFrame);
cmd.Parameters.AddWithValue("@pctAccountRisked", pctAccountRisked);
// optional parameters
if (MAEPips.HasValue)
cmd.Parameters.AddWithValue("@MAEPips", MAEPips);
if (MFEPips.HasValue)
cmd.Parameters.AddWithValue("@MFEPips", MFEPips);
if (tradeGrade.HasValue)
cmd.Parameters.AddWithValue("@tradeGrade", tradeGrade);
if (executionGrade.HasValue)
cmd.Parameters.AddWithValue("@executionGrade", executionGrade);
return (InsertData(cmd, "trade"));
}
public int InsertOrder(
int tradeId,
int units,
string side,
decimal price,
decimal spread,
int strategyId,
string signalTypeId,
int brokerId,
string orderTypeId,
DateTime orderDateTime,
string comment,
int? accountId = null
)
{
SqlCommand cmd = new SqlCommand("usp_InsertOrder");
// required parameters
cmd.Parameters.Add(new SqlParameter("@tradeId", tradeId));
cmd.Parameters.Add(new SqlParameter("@units", units));
cmd.Parameters.Add(new SqlParameter("@side", side));
cmd.Parameters.Add(new SqlParameter("@price", price));
cmd.Parameters.Add(new SqlParameter("@spread", spread));
cmd.Parameters.Add(new SqlParameter("@strategyId", strategyId));
cmd.Parameters.Add(new SqlParameter("@signalTypeId", signalTypeId));
cmd.Parameters.Add(new SqlParameter("@brokerId", brokerId));
cmd.Parameters.Add(new SqlParameter("@orderTypeId", orderTypeId));
cmd.Parameters.Add(new SqlParameter("@orderDateTime", orderDateTime));
cmd.Parameters.Add(new SqlParameter("@comment", comment));
// optional parameters
if (accountId.HasValue)
cmd.Parameters.Add(new SqlParameter("@accountId", accountId));
return (InsertData(cmd, "order"));
}
private int InsertData(SqlCommand cmd, string tableName)
{
SqlConnection con = new SqlConnection(_connectionString);
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
int rc = -1;
try
{
con.Open();
rc = (int) cmd.ExecuteScalar();
}
finally
{
con.Close();
}
return rc;
}
}
我从 ASP.NET 页面访问该代码,如下所示:
int tradeId = DB.InsertTrade (
ddlSymbols.SelectedValue,
ddlTradeSetups.SelectedValue,
int.Parse(ddlTradeTypes.SelectedValue),
decimal.Parse(txtLotsPerUnit.Text),
ddlTimeFrames.Text,
decimal.Parse(txtAcctRisk.Text));
int orderId = DB.InsertOrder (
tradeId,
int.Parse(txtUnits.Text),
radSide.SelectedValue,
Decimal.Parse(txtEntryPrice.Text),
Decimal.Parse(txtSpread.Text),
int.Parse(ddlStrategies.SelectedValue),
"IE",
int.Parse(ddlBrokers.SelectedValue),
radSide.SelectedValue + radOrderType.SelectedValue,
DateTime.Parse(txtEntryDate.Text + " " + txtEntryTime.Text),
txtEntryComments.Text,
int.Parse(ddlAccounts.SelectedValue));
我想要做的是将来自 ASP.NET 页面的调用包装在 SqlTransaction 中。最好的方法是什么?我需要稍微重构我的代码吗?
非常感谢。
I have a class with all my data access code in it for my ASP.NET 4.0 application. There are two methods in the class which insert data into the database. I want to enlist these inserts in a SqlTransaction and roll the transaction back if one of the inserts fail. However I'm not sure how to do it though, because of the way I've coded it. Here's my data access code:
public class DBUtil
{
private static readonly string _connectionString;
static DBUtil()
{
_connectionString = WebConfigurationManager.ConnectionStrings["MooDB"].ConnectionString;
if (string.IsNullOrEmpty(_connectionString))
throw new Exception("Connection string not configured in Web.Config file");
}
public int InsertTrade(
string symbol,
string tradeSetupId,
int tradeTypeId,
decimal lotsPerUnit,
string chartTimeFrame,
decimal pctAccountRisked,
int? tradeGrade = null,
int? executionGrade = null,
int? MFEPips = null,
int? MAEPips = null
)
{
SqlCommand cmd = new SqlCommand("usp_InsertTrade");
// required parameters
cmd.Parameters.AddWithValue("@symbol", symbol);
cmd.Parameters.AddWithValue("@tradeSetupId", tradeSetupId);
cmd.Parameters.AddWithValue("@tradeTypeId", tradeTypeId);
cmd.Parameters.AddWithValue("@lotsPerUnit", lotsPerUnit);
cmd.Parameters.AddWithValue("@chartTimeFrame", chartTimeFrame);
cmd.Parameters.AddWithValue("@pctAccountRisked", pctAccountRisked);
// optional parameters
if (MAEPips.HasValue)
cmd.Parameters.AddWithValue("@MAEPips", MAEPips);
if (MFEPips.HasValue)
cmd.Parameters.AddWithValue("@MFEPips", MFEPips);
if (tradeGrade.HasValue)
cmd.Parameters.AddWithValue("@tradeGrade", tradeGrade);
if (executionGrade.HasValue)
cmd.Parameters.AddWithValue("@executionGrade", executionGrade);
return (InsertData(cmd, "trade"));
}
public int InsertOrder(
int tradeId,
int units,
string side,
decimal price,
decimal spread,
int strategyId,
string signalTypeId,
int brokerId,
string orderTypeId,
DateTime orderDateTime,
string comment,
int? accountId = null
)
{
SqlCommand cmd = new SqlCommand("usp_InsertOrder");
// required parameters
cmd.Parameters.Add(new SqlParameter("@tradeId", tradeId));
cmd.Parameters.Add(new SqlParameter("@units", units));
cmd.Parameters.Add(new SqlParameter("@side", side));
cmd.Parameters.Add(new SqlParameter("@price", price));
cmd.Parameters.Add(new SqlParameter("@spread", spread));
cmd.Parameters.Add(new SqlParameter("@strategyId", strategyId));
cmd.Parameters.Add(new SqlParameter("@signalTypeId", signalTypeId));
cmd.Parameters.Add(new SqlParameter("@brokerId", brokerId));
cmd.Parameters.Add(new SqlParameter("@orderTypeId", orderTypeId));
cmd.Parameters.Add(new SqlParameter("@orderDateTime", orderDateTime));
cmd.Parameters.Add(new SqlParameter("@comment", comment));
// optional parameters
if (accountId.HasValue)
cmd.Parameters.Add(new SqlParameter("@accountId", accountId));
return (InsertData(cmd, "order"));
}
private int InsertData(SqlCommand cmd, string tableName)
{
SqlConnection con = new SqlConnection(_connectionString);
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
int rc = -1;
try
{
con.Open();
rc = (int) cmd.ExecuteScalar();
}
finally
{
con.Close();
}
return rc;
}
}
I am accessing that code from my ASP.NET page like so:
int tradeId = DB.InsertTrade (
ddlSymbols.SelectedValue,
ddlTradeSetups.SelectedValue,
int.Parse(ddlTradeTypes.SelectedValue),
decimal.Parse(txtLotsPerUnit.Text),
ddlTimeFrames.Text,
decimal.Parse(txtAcctRisk.Text));
int orderId = DB.InsertOrder (
tradeId,
int.Parse(txtUnits.Text),
radSide.SelectedValue,
Decimal.Parse(txtEntryPrice.Text),
Decimal.Parse(txtSpread.Text),
int.Parse(ddlStrategies.SelectedValue),
"IE",
int.Parse(ddlBrokers.SelectedValue),
radSide.SelectedValue + radOrderType.SelectedValue,
DateTime.Parse(txtEntryDate.Text + " " + txtEntryTime.Text),
txtEntryComments.Text,
int.Parse(ddlAccounts.SelectedValue));
What I want to do is wrap the calls from the ASP.NET page in a SqlTransaction. What is the best way to do this? Will I have to refactor my code somewhat?
Thanks very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
TransactionScope
对象将多个语句放入一个事务中:Use the
TransactionScope
object to put several statements within one transaction:在应用程序中插入新数据的方式不是事务保存。
您应该在同一事务和可能的连接中重构所有代码。
快速而肮脏的修复方法是创建一个连接,打开事务并将连接传递给每个方法,而不是在方法内创建新连接......在调用所有方法并且没有指示异常/错误之后提交< /strong> 事务,否则回滚它。
我认为这会很困难,但是我会考虑使用一些 ORM 映射器,例如 nHibernate。
成熟的地图制作者可以处理许多不同的场景,包括您的场景。
The way you are inserting new data in your application is not transaction save.
You should refactor your code all that within the same transaction and probably connection.
Quick and dirty fix for that is to create a connection, open transaction and pass the connection to every method, instead of creating new connections within the methods... After all methods are invoked and no exceptions/errors were indicated Commit the transaction, otherwise Rollback it.
I assume that t would be difficult but, I would consider using some ORM mappers like nHibernate.
Mature mappers can handle a lot of different scenarios including yours.
或者使用 SqlTransaction 类:
}
Or using the SqlTransaction class:
}