zoukankan      html  css  js  c++  java
  • .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对数据库事务处理的差异性 

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/dooom/p/1674747.html
Copyright © 2011-2022 走看看