原理:需要开启事务的Action贴上Transaction标签,则Action执行前开启事务,Action执行完提交事务,如果Action报错,则回滚事务。
OracleHelper代码:
using System; System.Collections; System.Collections.Generic; System.ComponentModel; System.Configuration; System.Data; System.Data.OracleClient; System.Linq; System.Reflection; System.Text; System.Web; System.Xml.Linq; System.Data.Objects.DataClasses; Models; namespace DBHelper { /// <summary> /// Oracle操作类 2015年6月20日 写程序之前,首先引用System.Data.OracleClient </summary> public class OracleHelper { #region 静态变量 <summary> 数据库连接字符串 </summary> private static string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString(); #endregion #region OracleConnection 获取数据库连接 获取数据库连接 static OracleConnection GetConn() { OracleConnection connection = null; string key = Simpo2016_OracleConnectionif (HttpContext.Current.Items[key] == ) { connection = new OracleConnection(connectionString); connection.Open(); HttpContext.Current.Items[key] = connection; } else { connection = (OracleConnection)HttpContext.Current.Items[key]; } return connection; } #region OracleTransaction 获取事务对象 获取事务对象 OracleTransaction GetTran() { OracleTransaction tran = Simpo2016_OracleTransaction) { tran = GetConn().BeginTransaction(); HttpContext.Current.Items[key] = tran; } { tran = (OracleTransaction)HttpContext.Current.Items[key]; } tran; } #region 开起事务标志 事务标志 string tranFlagKey = Simpo2016_OracleTransaction_Flag; 添加事务标志 void AddTranFlag() { HttpContext.Current.Items[tranFlagKey] = true; } 移除事务标志 RemoveTranFlag() { HttpContext.Current.Items[tranFlagKey] = falsebool TranFlag { get { bool tranFlag = ; if (HttpContext.Current.Items[tranFlagKey] != ) { tranFlag = ()HttpContext.Current.Items[tranFlagKey]; } tranFlag; } } #region 用于查询的数据库连接 用于查询的数据库连接 private OracleConnection m_Conn; #region 构造函数 public OracleHelper() { m_Conn = OracleConnection(connectionString); } #region 基础方法 #region 执行简单SQL语句 #region Exists bool Exists(string sqlString) { using (OracleCommand cmd = OracleCommand(sqlString,m_Conn)) { try { m_Conn.Open(); object obj = cmd.ExecuteScalar(); if ((Object.Equals(obj,null)) || (Object.Equals(obj,System.DBNull.Value))) { return ; } { ; } } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); m_Conn.Close(); } } } #region 执行SQL语句,返回影响的记录数 执行SQL语句,返回影响的记录数 </summary> <param name="sqlString">SQL语句</param> <returns>影响的记录数</returns> int ExecuteSql( sqlString) { OracleConnection connection = GetConn(); { if (connection.State != ConnectionState.Open) connection.Open(); if (TranFlag) cmd.Transaction = GetTran(); int rows = cmd.ExecuteNonQuery(); rows; } throw Exception(ex.Message); } { cmd.Dispose(); if (!TranFlag) connection.Close(); } } } #region 执行一条计算查询结果语句,返回查询结果 执行一条计算查询结果语句,返回查询结果(object) 计算查询结果语句查询结果(object)object GetSingle( obj; } } #region 执行查询语句,返回SQLiteDataReader 执行查询语句,返回SQLiteDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close ) 查询语句SQLiteDataReaderpublic OracleDataReader ExecuteReader( sqlString) { OracleConnection connection = OracleConnection(connectionString); OracleCommand cmd = { connection.Open(); OracleDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); myReader; } (Exception ex) { ex; } } #region 执行查询语句,返回DataSet 执行查询语句,返回DataSet DataSetpublic DataSet Query(using (OracleConnection connection = OracleConnection(connectionString)) { DataSet ds = DataSet(); { connection.Open(); OracleDataAdapter command = OracleDataAdapter(sqlString,connection); command.Fill(ds,ds); } { connection.Close(); } ds; } } #endregion #region 执行带参数的SQL语句 <param name="SQLString">string SQLString,1)">params OracleParameter[] cmdParms) { OracleConnection connection = OracleCommand()) { { PrepareCommand(cmd,connection,,SQLString,cmdParms); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); <param name="strSQL">string sqlString,1)"> OracleParameter[] cmdParms) { OracleCommand cmd = OracleCommand(); { PrepareCommand(cmd,m_Conn,sqlString,cmdParms); OracleDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); cmd.Parameters.Clear(); ex; } } OracleCommand(); PrepareCommand(cmd,cmdParms); using (OracleDataAdapter da = OracleDataAdapter(cmd)) { DataSet ds = { da.Fill(ds,1)">); cmd.Parameters.Clear(); } { cmd.Dispose(); m_Conn.Close(); } #region PrepareCommand void PrepareCommand(OracleCommand cmd,OracleConnection conn,OracleTransaction trans,1)"> cmdText,OracleParameter[] cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = CommandType.Text; if (cmdParms != ) { foreach (OracleParameter parm in cmdParms) { cmd.Parameters.Add(parm); } } } #region 增删改查 #region 获取最大编号 获取最大编号 <typeparam name="T">实体Model</typeparam> <param name="key">主键</param> int GetMaxID<T>( key) { Type type = typeof(T); string sql = string.Format(SELECT Max({0}) FROM {1} OracleCommand(sql,1)">return 1int.Parse(obj.ToString()) + #region 添加 添加 void Insert(object obj) { StringBuilder strSql = StringBuilder(); Type type = obj.GetType(); strSql.Append(insert into {0}( GetEntityProperties(type); List<string> propertyNameList = new List<string>(); foreach (PropertyInfo propertyInfo propertyInfoList) { propertyNameList.Add(propertyInfo.Name); } strSql.Append({0})",1)">string.Join( values ({0})string>(a => :" + a).ToArray()))); OracleParameter[] parameters = OracleParameter[propertyInfoList.Length]; for (int i = 0; i < propertyInfoList.Length; i++) { PropertyInfo propertyInfo = propertyInfoList[i]; object val = propertyInfo.GetValue(obj,1)">); OracleParameter oracleParameter = new OracleParameter(" + propertyInfo.Name,val == null ? DBNull.Value : val); parameters[i] = oracleParameter; } ExecuteSql(strSql.ToString(),parameters); } #region 修改 修改 void Update( obj) { object oldObj = Find(obj); if (oldObj == null) new Exception(无法获取到旧数据); StringBuilder strSql = update {0} int savedCount = 0; propertyInfoList) { object oldVal = propertyInfo.GetValue(oldObj,1)">); .Equals(oldVal,val)) { propertyNameList.Add(propertyInfo.Name); savedCount++; } } strSql.Append( set )); OracleParameter[] parameters = OracleParameter[savedCount]; StringBuilder sbPros = StringBuilder(); int k = {0}=:{0},propertyInfo.Name)); OracleParameter oracleParameter = DBNull.Value : val); parameters[k++] = oracleParameter; } } if (sbPros.Length > ) { strSql.Append(sbPros.ToString(0,sbPros.Length - )); } strSql.Append( where {0}='{1}'if (savedCount > ) { ExecuteSql(strSql.ToString(),parameters); } } #region 删除 根据Id删除 void Delete<T>(int id) { Type type = (T); StringBuilder sbSql = StringBuilder(); sbSql.Append(delete from {0} where {2}='{1}' 根据Id集合删除 void BatchDelete<T>( ids) { if (string.IsNullOrWhiteSpace(ids)) ; Type type = delete from {0} where {2} in ({1}) 根据条件删除 conditions) { string.IsNullOrWhiteSpace(conditions)) delete from {0} where {1}#region 获取实体 #region 根据实体获取实体 根据实体获取实体 object Find( obj) { Type type = obj.GetType(); object result = Activator.CreateInstance(type); bool hasValue = ; IDataReader rd = select * from {0} where {2}='{1}' { rd = ExecuteReader(sql); PropertyInfo[] propertyInfoList = GetEntityProperties(type); int fcnt = rd.FieldCount; List<string> fileds = (); 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { hasValue = ; IDataRecord record = rd; foreach (PropertyInfo pro propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(result,record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name],pro.PropertyType),1)">); } } } ex; } if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } if (hasValue) { result; } ; } } #region 根据Id获取实体 根据Id获取实体 object FindById(Type type,1)"> id) { Activator.CreateInstance(type); IDataReader rd = public T FindById<T>(string id) where T : () { Type type = (T); T result = (T)Activator.CreateInstance(type); IDataReader rd = default(T); } } #region 根据sql获取实体 根据sql获取实体 public T FindBySql<T>(string sql) #region 获取列表 获取列表 public List<T> FindListBySql<T>(() { List<T> list = new List<T> obj; IDataReader rd = ExecuteReader(sql); typeof(T) == typeof()) { (rd.Read()) { list.Add((T)rd[]); } } else { PropertyInfo[] propertyInfoList = ((T)).GetProperties(); rd.FieldCount; List<(); ) { fileds.Add(rd.GetName(i).ToUpper()); } (rd.Read()) { IDataRecord record = rd; obj = T(); propertyInfoList) { DBNull.Value) { ; } pro.SetValue(obj,1)">); } list.Add((T)obj); } } } list; } string sql,1)">params OracleParameter[] cmdParms) ExecuteReader(sql,cmdParms); #region 分页获取列表 分页(任意entity,尽量少的字段) public PagerModel FindPageBySql<T>(string orderby,1)">int pageSize,1)">int currentPage) () { PagerModel pagerModel = PagerModel(); OracleConnection(connectionString)) { connection.Open(); string commandText = select count(*) from ({0}) T OracleCommand(commandText,connection); pagerModel.totalRows = .Parse(cmd.ExecuteScalar().ToString()); int startRow = pageSize * (currentPage - int endRow = startRow + pageSize; StringBuilder sb = StringBuilder(); sb.Append(select * from ( select row_limit.*,rownum rownum_ from (); sb.Append(sql); string.IsNullOrWhiteSpace(orderby)) { sb.Append(" ); sb.Append(); } sb.Append( ) row_limit where rownum <= ); sb.Append(endRow); sb.Append( ) where rownum_ >); sb.Append(startRow); List<T> list = FindListBySql<T>(sb.ToString()); pagerModel.result = list; } pagerModel; } <typeparam name="T"></typeparam> <param name="sql"></param> <returns></returns> int currentPage,sql); OracleCommand cmd = .Parse(cmd.ExecuteScalar().ToString()); cmd.Parameters.Clear(); (sb.ToString(),cmdParms); pagerModel.result = pagerModel; } public DataSet FindPageBySql(out int totalCount,1)"> OracleParameter[] cmdParms) { DataSet ds = ); sb.Append(startRow); ds = Query(sql,cmdParms); } ds; } #region getReaderValue 转换数据 转换数据 Object getReaderValue(Object rdValue,Type ptype) { if (ptype == double)) Convert.ToDouble(rdValue); decimal Convert.ToDecimal(rdValue); Convert.ToInt32(rdValue); long Convert.ToInt64(rdValue); (DateTime)) Convert.ToDateTime(rdValue); typeof(Nullable<double>decimal>int>long>typeof(Nullable<DateTime> rdValue; } #region 获取主键名称 获取主键名称 GetIdName(Type type) { PropertyInfo[] propertyInfoList = GetEntityProperties(type); if (propertyInfo.GetCustomAttributes(typeof(IsIdAttribute),1)">false).Length > ) { propertyInfo.Name; } } Id; } #region 获取主键值 object GetIdVal( val) { string idName = GetIdName(val.GetType()); .IsNullOrWhiteSpace(idName)) { return val.GetType().GetProperty(idName).GetValue(val,1)">); } #region 获取实体类属性 获取实体类属性 PropertyInfo[] GetEntityProperties(Type type) { List<PropertyInfo> result = new List<PropertyInfo>(); PropertyInfo[] propertyInfoList = type.GetProperties(); typeof(EdmRelationshipNavigationPropertyAttribute),1)">false).Length == 0 && propertyInfo.GetCustomAttributes(typeof(BrowsableAttribute),1)">) { result.Add(propertyInfo); } } result.ToArray(); } #region 事务 #region 开始事务 开始事务 BeginTransaction() { GetTran(); AddTranFlag(); } #region 提交事务 提交事务 CommitTransaction() { if (GetConn().State == ConnectionState.Open) { GetTran().Commit(); RemoveTranFlag(); } } (Exception ex) { GetTran().Rollback(); RemoveTranFlag(); } ConnectionState.Open) GetConn().Close(); } } #region 回滚事务(出错时调用该方法回滚) 回滚事务(出错时调用该方法回滚) RollbackTransaction() { GetTran().Rollback(); RemoveTranFlag(); GetConn().Close(); } #endregion } }
在MVC4项目的FilterConfig.cs文件中,添加ActionFilter拦截器:
System.Web.Mvc; Common; TechReport.Web { FilterConfig { RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add( HandleErrorAttribute()); filters.Add( ActionFilter()); } } }
ActionFilter拦截器代码:
DBHelper; Common { Action拦截器 ActionFilter : FilterAttribute,IActionFilter { //在执行操作方法之前调用 OnActionExecuting(ActionExecutingContext filterContext) { MethodInfo method = filterContext.Controller.GetType().GetMethod(filterContext.ActionDescriptor.ActionName); object[] transactionAttributes = method.GetCustomAttributes(typeof(TransactionAttribute),1)">); if (transactionAttributes.Length > ) { OracleHelper.BeginTransaction(); } } 在执行操作方法后调用 OnActionExecuted(ActionExecutedContext filterContext) { MethodInfo method =if (filterContext.Exception == ) { OracleHelper.CommitTransaction(); } { OracleHelper.RollbackTransaction(); filterContext.ExceptionHandled = ; ContentResult contentResult = ContentResult(); contentResult.Content = filterContext.Exception.Message; filterContext.Result = contentResult; } } } } }
TransactionAttribute类:
System.Text; 开启事务,添加此特性的方法不要使用try catch,若要使用,catch中应将错误再次抛出 </summary> [Serializable,AttributeUsage(AttributeTargets.Method)] TransactionAttribute : Attribute { } }
在Action上添加[Transaction]标签:
[Transaction] public ActionResult Submit( reportCode) { string strParams = Request[params]; REPORTAUDIT reportAudit = REPORTAUDIT(); REPORTFLOW reportFlow = REPORTFLOW(); SYS_USER empdetail = m_UserDal.Get(strParams.Get(AUDITUSERNAME)); reportAudit.AUDITUSERNAME = strParams.Get(); reportAudit.AUDITEMPNAME = empdetail.EMPNAME; reportAudit.AUDITTYPE = ()Enums.AuditType.审核; reportAudit.ISFINISHED = ; reportAudit.REPORTCODE = reportCode; reportAudit.TASKTIME = DateTime.Now; long auditSID = m_ReportAudit_DAL.GetAuditSID(reportCode,2); (m_ReportAudit_DAL.Exists(auditSID)) { if (m_ReportAudit_DAL.Get(auditSID).ISFINISHED == ) { return Content(正在提交,请稍后!); } { reportAudit.AUDITSID = auditSID; m_ReportAudit_DAL.Update(reportAudit); } } { reportAudit.AUDITSID = m_ReportAudit_DAL.GetMaxID(); m_ReportAudit_DAL.Insert(reportAudit); } reportFlow.FLOWSERIALID = m_ReportFlow_DAL.GetMaxID(); reportFlow.OPERATOREMPNAME = AdminUtil.LoginUser.EMPNAME; reportFlow.OPRATORUSERNAME = AdminUtil.LoginUser.USERNAME; reportFlow.OPERATORTIME = DateTime.Now; reportFlow.OPERATORTYPE = 4; reportFlow.OPINION = strParams.Get(OPINION); REPORT report = m_Report_DAL.GetByReportCode(reportCode); report.CALLBACKSTATE = ; report.REPORTSTATEID = ()Enums.ReportState.待审核; report.SYSTAR = int.Parse(strParams.Get(SYSTAR)); report.SECLEVELID = SECLEVELID)); report.COVERID = long.Parse(strParams.Get(COVERID)); m_Report_DAL.Update(report); int flag = Convert.ToInt32(report.COVERID); REPORTFILE reportFile = m_ReportFile_DAL.Get(reportCode); if (reportFile != ) { string filename = Server.MapPath(m_ReportFile_DAL.Get(reportCode).FILEADDR.ToString()); if ((flag != 6) && (flag != 7)) { AddPageInfo(filename,flag,reportCode); } } m_ReportFlow_DAL.Insert(reportFlow); OK); }
DAL示例:
DBHelper; DAL { /// ReportAudit_DAL { #region 变量 private OracleHelper dbHelper = OracleHelper(); #region 添加 Insert(REPORTAUDIT model) { dbHelper.Insert(model); } } }