用法一:
代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作。
首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一个连接、事务完成关闭同一个连接的一个共有类
- <span style="font-size:18px;">using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Data;
- using System.Data.SqlClient;
- using Maticsoft.DBUtility;
- namespace PersonalFiles.DAL
- {
- public class DBTransaction
- {
- private DbHelperSQL SqlHelper = null;
- public DBTransaction()
- {
- SqlHelper = new DbHelperSQL();
- }
- /// <summary>
- /// 获取数据库连接
- /// </summary>
- /// <returns></returns>
- public SqlConnection GetConnection()
- {
- return SqlHelper.GetCon();
- }
- /// <summary>
- /// 获取事务
- /// </summary>
- /// <returns></returns>
- public SqlTransaction GetTransaction(SqlConnection conn)
- {
- return conn.BeginTransaction();
- }
- /// <summary>
- /// 提交事务
- /// </summary>
- public void Commit(SqlTransaction sqlTransaction)
- {
- sqlTransaction.Commit();
- }
- /// <summary>
- /// 回滚事务
- /// </summary>
- public void Rollback(SqlTransaction sqlTransaction)
- {
- sqlTransaction.Rollback();
- }
- /// <summary>
- /// 关闭连接
- /// </summary>
- public void Close(SqlConnection conn)
- {
- if (conn.State == ConnectionState.Open)
- {
- conn.Close();
- }
- }
- }
- }
- </span>
界面层的后台代码和以前一样直接调去就行了,现在来看主要是在B层中的代码发生了很大的变化,需要向下层传递事务与获取的连接
- <span style="font-size:18px;">/// <summary>
- /// 增加一条数据
- /// </summary>
- public void Add(PersonalFiles.Model.BasicInformation modelBasic, PersonalFiles.Model.T_HumanAgency model)
- {
- int flag = 0;
- DBTransaction DbTran = new DBTransaction();
- //获得连接
- SqlConnection conn = DbTran.GetConnection();
- //开启事务
- SqlTransaction trans = DbTran.GetTransaction(conn);
- try
- {
- //把获得的同一个连接与事务一共传下去
- //dalBasic.Add(modelBasic,conn,trans);
- //把获得的同一个连接与事务一共传下去
- dalAgency.Add(model,conn,trans);
- //事务提交
- DbTran.Commit(trans);
- //return true;
- }
- catch (Exception ex)
- {
- //回滚事务
- DbTran.Rollback(trans);
- }
- finally
- {
- DbTran.Close(conn);
- }
- }</span>
注意的是向D层传是我们需要传的是B层获取的同一个连接于开启的是一个事务:
- <span style="font-size:18px;">/// <summary>
- /// 增加一条数据
- /// </summary>
- public void Add(PersonalFiles.Model.T_HumanAgency model,SqlConnection conn,SqlTransaction trans)
- {
- StringBuilder strSql = new StringBuilder();
- strSql.Append("insert into T_HumanAgency(");
- strSql.Append("myidentity,relation,receivemode,workingtime,intotime,oldworkplace,nowworkplace,inervice,registered,registeredcardid,registeredid,householder,isrecord,fileintotime,fileouttime,filetowhere,relationouttime,Paymentstandard,paymentsmonth,payments,stoptime,state,pri,admin,ID)");
- strSql.Append(" values (");
- strSql.Append("@myidentity,@relation,@receivemode,@workingtime,@intotime,@oldworkplace,@nowworkplace,@inervice,@registered,@registeredcardid,@registeredid,@householder,@isrecord,@fileintotime,@fileouttime,@filetowhere,@relationouttime,@Paymentstandard,@paymentsmonth,@payments,@stoptime,@state,@pri,@admin,@ID)");
- SqlParameter[] parameters = {
- new SqlParameter("@myidentity", SqlDbType.VarChar,50),
- new SqlParameter("@relation", SqlDbType.VarChar,50),
- new SqlParameter("@receivemode", SqlDbType.VarChar,50),
- new SqlParameter("@workingtime", SqlDbType.VarChar,50),
- new SqlParameter("@intotime", SqlDbType.VarChar,50),
- new SqlParameter("@oldworkplace", SqlDbType.VarChar,50),
- new SqlParameter("@nowworkplace", SqlDbType.VarChar,50),
- new SqlParameter("@inervice", SqlDbType.VarChar,50),
- new SqlParameter("@registered", SqlDbType.VarChar,50),
- new SqlParameter("@registeredcardid", SqlDbType.VarChar,50),
- new SqlParameter("@registeredid", SqlDbType.VarChar,50),
- new SqlParameter("@householder", SqlDbType.VarChar,50),
- new SqlParameter("@isrecord", SqlDbType.VarChar,50),
- new SqlParameter("@fileintotime", SqlDbType.VarChar,50),
- new SqlParameter("@fileouttime", SqlDbType.VarChar,50),
- new SqlParameter("@filetowhere", SqlDbType.VarChar,50),
- new SqlParameter("@relationouttime", SqlDbType.VarChar,50),
- new SqlParameter("@Paymentstandard", SqlDbType.VarChar,50),
- new SqlParameter("@paymentsmonth", SqlDbType.VarChar,50),
- new SqlParameter("@payments", SqlDbType.VarChar,50),
- new SqlParameter("@stoptime", SqlDbType.VarChar,50),
- new SqlParameter("@state", SqlDbType.VarChar,50),
- new SqlParameter("@admin", SqlDbType.VarChar,50),
- new SqlParameter("@pri", SqlDbType.VarChar,50),
- new SqlParameter("@ID", SqlDbType.VarChar,50)};
- parameters[0].Value = model.myidentity;
- parameters[1].Value = model.relation;
- parameters[2].Value = model.receivemode;
- parameters[3].Value = model.workingtime;
- parameters[4].Value = model.intotime;
- parameters[5].Value = model.oldworkplace;
- parameters[6].Value = model.nowworkplace;
- parameters[7].Value = model.inervice;
- parameters[8].Value = model.registered;
- parameters[9].Value = model.registeredcardid;
- parameters[10].Value = model.registeredid;
- parameters[11].Value = model.householder;
- parameters[12].Value = model.isrecord;
- parameters[13].Value = model.fileintotime;
- parameters[14].Value = model.fileouttime;
- parameters[15].Value = model.filetowhere;
- parameters[16].Value = model.relationouttime;
- parameters[17].Value = model.Paymentstandard;
- parameters[18].Value = model.paymentsmonth;
- parameters[19].Value = model.payments;
- parameters[20].Value = model.stoptime;
- parameters[21].Value = model.state;
- parameters[22].Value = model.pri;
- parameters[23].Value = model.admin;
- parameters[24].Value = model.ID;
- //DbHelperSQL.ExecuteSql(strSql.ToString(), parameters);
- DbHelperSQL.ExecuteSql(strSql.ToString(),conn,trans, parameters);
- }</span>
在代码中添加事务与存储过程中添加事务的异同
不同点:
1:代码中添加事务的好处是:增加了代码的可读性、与可维护性,方便后期人员维护系统看代码能够一目了然的看懂代码,而在数据库中添加存储过程的可读性不是很好。
2:为什么不建议使用数据库自带的存储过程+事务呢?主要是一个项目过多的依赖数据库,这样对后期的数据库迁移都会带来一定的影响与不便(sql向oracle迁移),好多转换不是很容易兼容性和不是很好。
用法二:
直接在数据交互层操作:
public bool CreateSpec(Spec spec, ClassificationRelatedSpec crs, string currentUserAccount)
{
try
{
spec.SpecIID = Guid.NewGuid().ToString();
crs.IID = Guid.NewGuid().ToString();
//商品规格信息
SqlParameter[] param =
{
new SqlParameter("@SpecIID", SqlDbType.UniqueIdentifier),
new SqlParameter("@SpName", SqlDbType.NVarChar),
new SqlParameter("@SpSort", SqlDbType.Int),
new SqlParameter("@SpecFormat", SqlDbType.NVarChar),
new SqlParameter("@SpecValue", SqlDbType.NVarChar),
new SqlParameter("@SpecURL", SqlDbType.NVarChar),
new SqlParameter("@CreateDateTime", SqlDbType.DateTime),
new SqlParameter("@ModifieDateTime", SqlDbType.DateTime),
new SqlParameter("@Operation", SqlDbType.NVarChar)
};
int index = 0;
param[index++].Value = new Guid(spec.SpecIID);
param[index++].Value = spec.SpName;
param[index++].Value = spec.SpSort;
param[index++].Value = spec.SpecFormat;
param[index++].Value = spec.SpecValue;
param[index++].Value = spec.SpecURL;
param[index++].Value = DateTime.Now;
param[index++].Value = DateTime.Now;
param[index++].Value = currentUserAccount;
//商品规格分类关联信息
SqlParameter[] crsParam =
{
new SqlParameter("@IID", SqlDbType.UniqueIdentifier),
new SqlParameter("@ClassificationIID", SqlDbType.NVarChar ),
new SqlParameter("@SpecIID", SqlDbType.NVarChar)
};
crsParam[0].Value = new Guid(crs.IID);
crsParam[1].Value = crs.ClassificationIID;
crsParam[2].Value = spec.SpecIID;
using (SqlConnection conn = new SqlConnection(TripConfig.ConnectionStringTourism))
{
conn.Open();//打开连接
using (SqlTransaction tran = conn.BeginTransaction())
{
try
{
SqlHelper.ExecuteNonQuery(tran, CommandType.StoredProcedure, Proc_AddSpec, param);
SqlHelper.ExecuteNonQuery(tran, CommandType.StoredProcedure, Proc_AddClassificationRelatedSpec, crsParam);
AddOperateLog(CommonConst.BizType_Platform, "创建商品规格和关联关系", spec.SpecIID, "成功", "创建商品规格和关联关系", spec.SpecIID, "EnityID IID", "", currentUserAccount);
tran.Commit();//提交事务
return true;
}
catch (Exception ex)
{
tran.Rollback();//事务回滚
Logger.WriteLog(ex);
return false;
}
finally
{
//释放资源
tran.Dispose();
if (conn != null && conn.State == ConnectionState.Open)
{
conn.Close();
}
}
}
}
}
catch (Exception)
{
throw;
}
}
用法三:
存储过程直接使用:
Create PROCEDURE [dbo].[Sp_ComplaintInfo_Remove]
@ID uniqueidentifier
AS
begin tran --开始执行事务
--01 更新投诉信息表
UPDATE ComplaintInfo SET [IsDel] ='1' WHERE ID=@ID
--02 更新投诉处理信息表
UPDATE ComplaintsDisposeInfo SET [IsDel] ='1' WHERE CID=@ID
if @@error<>0 --判断如果两条语句有任何一条出现错误
begin rollback tran --回滚
end
else --如何两条都执行成功
begin commit tran --执行这个事务的操作
end
GO