.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对数据库事务处理的差异性 

posted @ 2010-02-27 11:38  clound  阅读(1051)  评论(0编辑  收藏  举报