• .net 中隐式事务和显示事务的用法


     

    事务:指作为单个逻辑工作单元执行的一系列操作,而这些逻辑工作单元需要具有原子性,一致性,隔离性和持久性四个属性。统称为ACID属性。

    A:Atomicity 原子性(不可分性)

    原子性:指事务必须是原子工作单元,不可分隔性,即对于事务所进行数据修改,要么全部执行,要么全都不执行。

    C:Consistency 一致性

    指事务在完成时,必须使所有的数据都保持一致性状态,而且在相关数据库中,所有规则都必须应用于事务的修改。以保持所有数据的完整性

    也就是说,如果有多个表中放有一个人的信息,那如果你要修改这个人的信息,就必须多个表中的信息都要修改,不能有的修改,有的不修改。

    I:Isolation 隔离性

    事务与其他事务是隔离的,也就是说一个事务的一项工作对数据进行修改时,如果整个事务还没有结束,其他事务就无法知道这个数据发生了修改。

    D:Durability 持久性

    指事务完成之后,它对于系统的影响是永久性的,即使系统出现故障也是如此。比如说,我们把一个人的记录放在磁盘上这后,停电了,这个人的记录已经存在磁盘上了,不可能来电以后又没有了。

    事务的类型:隐式事务和显式事务
    1.显式事务(Explicit Transaction)
    显式事务是在程序中规定其提交、回滚。
    SQL Server版本:
    代码
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString))
    {
        conn.Open();
        
    using (SqlTransaction tran = conn.BeginTransaction())
        {
            
    using (SqlCommand cmd = new SqlCommand())
            {
                cmd.Connection 
    = conn;
                cmd.CommandType 
    = CommandType.Text;
                cmd.Transaction 
    = tran;
                
    try
                {
                    cmd.CommandText 
    = "insert into TranTable(Priority) values(1)";
                    cmd.ExecuteNonQuery();
                    cmd.CommandText 
    = "insert into TranTable(Priority) values(256)";
                    cmd.ExecuteNonQuery();
                    tran.Commit();
                    Response.Write(
    "Ok");
                }
                
    catch (SqlException ex)
                {
                    tran.Rollback();
                    Response.Write(
    "Error:" + ex.Message);
                }
            }
        }
        conn.Close();
    }
    oracle版本:
    代码
    using Microsoft.Practices.EnterpriseLibrary.Data;
    using Oracle.DataAccess.Client;
    using System.Collections.Generic;

    public  class DepInfoDAL:IDepInfo
      {
          
    private Database db;

          
    #region 构造函数

           
    public DepInfoDAL()
          {
              db 
    = DatabaseFactory.CreateDatabase("ConnectionString");
          }
          
    #endregion
          
          
    #region 
          
    public bool Del(string depinfoid, EnumSchoolState state)
          {
              
    using (OracleConnection cn = (OracleConnection)db.CreateConnection())
              {
                  cn.Open();
                  OracleTransaction transaction 
    = cn.BeginTransaction();
                  
    try
                  {
                      Del(depinfoid, state, transaction);
                      
                      AddNotice(depinfoid,transaction);

                      transaction.Commit();
                      
    return true;
                  }
                  
    catch (OracleException er)
                  {
                      transaction.Rollback();
                      
    return false;
                  }
              }
          }
           
    #endregion

          
    #region 
          
    public void Del(string depinfoid, EnumSchoolState state, OracleTransaction transaction)
          {
              
    string sql = "update depinfo set depstate=:PI_depstate where depinfoid=:PI_depinfoid";

              OracleCommand dbCommend 
    = (OracleCommand)db.GetSqlStringCommand(sql);
              OracleParameter[] orap 
    =
                {
                  
    new OracleParameter("PI_depstate",OracleDbType.Varchar2,((int)state).ToString(),ParameterDirection.Input),
                  
    new OracleParameter("PI_Depinfoid",OracleDbType.Varchar2,depinfoid,ParameterDirection.Input),
                };
              
    foreach (OracleParameter parm in orap)
              {
                  dbCommend.Parameters.Add(parm);
              }
              db.ExecuteNonQuery(dbCommend, transaction);

          }
          
    #endregion
           
          
    #region 
          
    public bool AddNotice(string depinfoid)
          {
              
    using (OracleConnection cn = (OracleConnection)db.CreateConnection())
              {
                  cn.Open();
                  OracleTransaction transaction 
    = cn.BeginTransaction();
                  
    try
                  {
                      Del(depinfoid, state, transaction);
                      
    //notice
                      
                      Add(depinfoid,state,transaction);

                      transaction.Commit();
                      
    return true;
                  }
                  
    catch (OracleException er)
                  {
                      transaction.Rollback();
                      
    return false;
                  }
              }
          }
           
    #endregion

          
    #region 
          
    public void AddNotice(string depinfoid, OracleTransaction transaction)
          {
              
    string sql = "Insert Into notice(noticeid,depinfoid,content) values (sq_notice_noticeid.nextval,:PI_depinfoid,:PI_content)";

              OracleCommand dbCommend 
    = (OracleCommand)db.GetSqlStringCommand(sql);
              OracleParameter[] orap 
    =
                {
                  
    new OracleParameter("PI_depinfoid",OracleDbType.Varchar2,depinfoid,ParameterDirection.Input),
                  
    new OracleParameter("PI_content",OracleDbType.Varchar2,"11111",ParameterDirection.Input),
                };
              
    foreach (OracleParameter parm in orap)
              {
                  dbCommend.Parameters.Add(parm);
              }
              db.ExecuteNonQuery(dbCommend, transaction);

          }
          
    #endregion

    }
     我们来看看显式事务的优缺点:
     优点:(1)操作简单(主要是对象几个方法)和数据库事务差不多
          (2)占用资源少、速度快
          (3)独立于数据库 不同数据库专有代码被隐藏了
    缺点:(1)事务不能跨多个数据库连接(分布式事务可以跨多个数据库)
          (2)事务执行必须依靠一个存在的数据库连接,从Transaction对象生成就可以看出通过SqlConnection或OracleConnection对象获得。
           (3)ADO.net中分布式事务可以跨多个数据库,如果其中一个是SQLServer数据库的话,通过SQLserver连接服务器连接别的数据库,但如果是DB2和Oracle之间就不行。
           比如您要在一个业务中同时实现往SQLServer数据Oracle数据库都插入数据的事务,就无法实现。
    2.隐式事务
      相对于显式事务,隐式事务不再有 Commit、Rollback 方法。只包含一个事务范围,在.net中可以使用System.Transactions 实现
    SQL Server版本:
    Oracle版本:
    //业务层
    代码
    public  class scoreBLL
        {
            
    public static void Get(string userinfoid)
            {
                
    using (TransactionScope scope = new TransactionScope())
                {
                    scoreDal SD 
    = new scoreDal();
                    
    try
                    {
                        
    //你的业务代码 
                        SD.Add(userinfoid, 1);
                        SD.reduce(userinfoid, 
    11);
                        
                        scope.Complete();
                    }
                    
    catch (Exception e)
                    {

                    }
                    
    finally
                    {
                          
                       // scope.Dispose();  使用using 会自动释放资源
                    }
                } 

            }
        }
     
     //数据层
    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using wdxt_Score.IDAL;

    using Microsoft.Practices.EnterpriseLibrary.Data;
    using Oracle.DataAccess.Client;
    using System.Data;

        
    public class scoreDal : Iscore
        {
            
    private Database db;

            
    public scoreDal()
            {
                db 
    = DatabaseFactory.CreateDatabase("ConnectionString");
            }
            
    public void Add(string userinfoid, int basevalue)
            {
                
    string sql = "Insert Into TEXT";
                sql 
    += "(ID,VALUE)";
                sql 
    += "values(:PI_userinfoid,:PI_basevalue)";
                OracleCommand dbCommend 
    = (OracleCommand)db.GetSqlStringCommand(sql);

                OracleParameter[] orap 
    =
                {
                  
    new OracleParameter("PI_userinfoid",OracleDbType.Varchar2,userinfoid,ParameterDirection.Input),
                  
    new OracleParameter("PI_basevalue",OracleDbType.Varchar2,basevalue,ParameterDirection.Input),
                };
                
    foreach (OracleParameter parm in orap)
                {
                    dbCommend.Parameters.Add(parm);
                }
                db.ExecuteNonQuery(dbCommend);
            }

            
    public void reduce(string userinfoid, int basevalue)
            {
                
    string sql = "Insert Into TEXT";
                sql 
    += "(ID,VALUE)";
                sql 
    += "values(:PI_userinfoid,:PI_basevalue)";
                OracleCommand dbCommend 
    = (OracleCommand)db.GetSqlStringCommand(sql);

                OracleParameter[] orap 
    =
                {
                  
    new OracleParameter("PI_userinfoid",OracleDbType.Varchar2,userinfoid,ParameterDirection.Input),
                  
    new OracleParameter("PI_basevalue",OracleDbType.Varchar2,basevalue,ParameterDirection.Input),
                };
                
    foreach (OracleParameter parm in orap)
                {
                    dbCommend.Parameters.Add(parm);
                }
                db.ExecuteNonQuery(dbCommend);

            }

        }

    上一个项目用三层架构事务都放在数据层,其实应该用隐式事务,放在业务层是最合适的。

    这篇写的都是在.net中的事务,还有在数据库中实现,利用com组件等,在数据库中使用事务又有所不同,

    有兴趣可以看看这篇文章Oracle与SQL Server事务处理的比较

     
    参考:1、.NET 事务技术

            4三种事务处理

            5MS SQL Server和Oracle对数据库事务处理的差异性 

  • 相关阅读:
    UVA 11525 好大好大的排列(线段树)
    UVA 11525 好大好大的排列(线段树)
    UVALive 4108城市天际线,混杂着递归与非递归的线段树
    UVALive 4108城市天际线,混杂着递归与非递归的线段树
    zencart搜索结果页面静态化 advanced_search_result
    .htaccess 一段神奇的跳转代码
    清除zencart分类页多页后面的&disp_order &sort字符串的方法
    zencart只有购买过此产品的客户才能评价产品
    mysql自增字段AUTO_INCREMENT重排或归零
    mysql语句修改zencart产品原价为特价的倍数
  • 原文地址:https://www.cnblogs.com/dooom/p/1674747.html
Copyright © 2020-2023  润新知