在开始介绍文章主要内容前先简单说一下事务

1.事务介绍

  事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。

2.事务使用场景

  需要对数据库同时进行多条更新操作时!例如,电商平台的下单付款,银行转账之类的


  好了,这里就不对事物进行细说了,想了解更多与事务有关的详细知识可以去园子里搜索哈

  执行事务的步骤

  1.连接数据库,连接数据库后会返回一个SqlConnection对象,我这里在数据库连接后将其赋值给了一个全局的SqlConnection对象——_con

  2.用返回的SqlConnection对象用BeginTransaction()方法生产并开始一个事务对象。

  3.执行所有对数据库进行更改操作的Sql语句。

   在对数据库进行更改时需要用到SqlCommand,在用生成SqlCommand对象后必须给其绑定事务(Transaction),不绑定会报错。

     在这里需要注意的是所有SqlCommand对象绑定的SqlConnection必须是同一个SqlConection对象,所有SqlCommand对象绑定的事务对象必须是同一个事务对象。若没绑定相同的SqlConnection对象和SqlTransaction,事务便会如同虚设。

  4.所有Sql语句执行成功后SqlTransaction对象可使用Commit()方法提交事务,失败则用Rollback()回滚事务,将数据库回滚到第一天sql执行前的状态。

  5.关闭数据库连接,释放资源。

  话不多说搬Code,注释代码上都有,如有不明白的地方或是有更好的意见请在下方留言区留下你的评论

事务方法

public static int ModifyDatabaseTran(List<string> SqlStrList, List<SqlParameter[]> SqlParList) {
int result = ;
//打开数据库连接
SqlConnection con = OpenDatabase();
//_con:全局SqlConnection对象
//生成事物对象
SqlTransaction tran = _con.BeginTransaction();
try
{
//遍历并执行SqlStrList集合里面的Sql语句
for (int i = ; i < SqlStrList.Count; i++)
{
//将Sql语句与其对应的SqlParameter[]绑定并生成SqlCommand对象
SqlCommand com = BulidCommand(SqlStrList[i], SqlParList[i]);
//给SqlCommand对象绑定事务,必须绑定同一个事务对象否则跑不出事务效果
com.Transaction = tran;
//返回受影响的行数
result = com.ExecuteNonQuery();
}
//若最后执行的sql是插入语句result的值便=0,这里将其值改为1告诉调用者sql语句执行成功
if (result == ) result = ;
//所有Sql语句执行成功后提交事务
tran.Commit(); }
catch (Exception)
{
//SqlStrList集合里面有一条Sql语句执行失败便执行事务回滚操作,回滚后报错Sql语句之前执行的Sql语句都将无效
//同时数据库恢复SqlStrList集合里面的Sql语句执行前的状态
          result=0;
tran.Rollback(); }
finally
{
//关闭数据库连接,释放资源
if (_con != null && _con.State != ConnectionState.Closed) {
_con.Close();
con.Dispose();
}
tran.Dispose(); }
//返回结果 0:失败,1:成功
return result;
}

打开数据库连接的方法

//数据库连接字符串
private const string conStr = "server=.;database=Food;uid=sa;pwd=123456"; private static SqlConnection _con; /// <summary>
/// 打开数据库连接
/// </summary>
/// <returns></returns>
private static SqlConnection OpenDatabase() {
if (_con == null || _con.State == ConnectionState.Closed)
{
_con = new SqlConnection(conStr);
_con.Open();
}
return _con;
}

生产SqlCommand对象方法

/// <summary>
/// 参数化查询绑定参数
/// </summary>
/// <param name="sqlStr"></param>
/// <param name="SqlPar"></param>
/// <returns></returns>
private static SqlCommand BulidCommand(string sqlStr,SqlParameter[] SqlPar) {
SqlConnection con = OpenDatabase();
SqlCommand com = new SqlCommand(sqlStr, con);
com.Parameters.AddRange(SqlPar);
return com;
}

实例

下面例子本来是想用winform写个注册,结界觉着拖控件太麻烦了,索性就直接在代码里面写sql了

页面(输入框可以自动忽略,这里只用到了按钮的点击事件)

执行操作前的member表状态

注册按钮点击事件代码(页面控件是从登陆页面复制过来的注册按钮的Name属性没有更改所以事件名称是LoginBtn_Click而不是RegisterBtn_Click)

private void LoginBtn_Click(object sender, EventArgs e)
{
List<string> sqlStr = new List<string>
{
{ @"insert member values(@MemberAccount,@Password)"},
{ @"insert member values(@MemberAccount,@Password)"}
};
List<SqlParameter[]> sqlPar = new List<SqlParameter[]>
{
new SqlParameter[] { new SqlParameter("@MemberAccount","lei1"), new SqlParameter("@Password", "") },
new SqlParameter[] { new SqlParameter("@MemberAccount","lei2"), new SqlParameter("@Password", "") }
}; int result=DBHlep.ModifyDatabaseTran(sqlStr,sqlPar);
if (result > )
{
MessageBox.Show("成功!");
}
else {
MessageBox.Show("失败!");
}
}

点击注册按钮后我们再来看看member表状态

上面的是Sql语句不报错的执行结果,接下来,我们将第二条sql语句的表名从menber改为menber1,看看member表的数据会发生什么变化

PS:我的数据库里面没有表member1所以第二条sql必定会执行失败,第二条sql失败后我们看看表member是否新增了一条数据(第一条sql是正确的,只修改了第二条sql的表名),新增了一条数据则事务执行失败,反之事务执行成功

private void LoginBtn_Click(object sender, EventArgs e)
{
List<string> sqlStr = new List<string>
{
{ @"insert member values(@MemberAccount,@Password)"},
//将第二条sql的表名修改为member1
{ @"insert member1 values(@MemberAccount,@Password)"}
};
List<SqlParameter[]> sqlPar = new List<SqlParameter[]>
{
new SqlParameter[] { new SqlParameter("@MemberAccount","lei1"), new SqlParameter("@Password", "") },
new SqlParameter[] { new SqlParameter("@MemberAccount","lei2"), new SqlParameter("@Password", "") }
}; int result=DBHlep.ModifyDatabaseTran(sqlStr,sqlPar);
if (result > )
{
MessageBox.Show("成功!");
}
else {
MessageBox.Show("失败!");
}
}

点击注册按钮后看表member的数据是否发生了变化

member表数据未发生变化,事务执行成功!

好了,这篇博客到这里就结束了,如有不明白之处或是有更好的意见请在下方留言区留下你的评论

AOD.NET实现数据库事物Transaction的更多相关文章

  1. 数据库事物四大特性-ACID

    事务的:原子性.一致性.分离性.持久性 事物(transaction)是由一些列操作序列构成的执行单元,这些单元要么都做,要么不做,是一个不可分割的工作单元. 数据库事物的四个基本性质(ACID) 1 ...

  2. SpringBoot事物Transaction实战讲解教程

    前言 本篇文章主要介绍的是SpringBoot的事物Transaction使用的教程. SpringBoot Transaction 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码 ...

  3. 数据库事物用法 SET XACT_ABORT ON

    数据库事物的用法和作用就不再重复,写一下在实战当中遇到的问题,代码如下: begin tran --开始执行事务     --语句一 update  set acount = acount-100 w ...

  4. Spring中的数据库事物管理

    Spring中的数据库事物管理 只要给方法加一个@Transactional注解就可以了 例如:

  5. 数据库事物 jdbc事物 spring事物 隔离级别:脏幻不可重复读

    1.数据库事物: 事物的概念 a给b打100块钱的例子 2.jdbc事物: 通过下面代码实现 private Connection conn = null; private PreparedState ...

  6. Spring+Mybatis+SpringMVC+Atomikos多数据源共存+不同数据库事物一致性处理

    网上找了一大堆的例子,没一个跑通的,都是copy转发,哎,整理得好辛苦..做个笔记,方便正遇到此问题的猿们能够得到帮助....废话不多说,贴代码..... 项目结构说明: 1.dao层的admin.w ...

  7. Spring 事物Transaction

    日常开发中Spring 为我们提供了两种事物的定义方式 XML 配置 方式 :这种方式配置起来比较麻烦,但后期比较好进行维护 注解方式:配置起来比较方便,也是日常开发常用的: 我们这里进行第二种注解的 ...

  8. 数据库事务(Transaction)

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...

  9. SQL Server 2008 中收缩数据库(DUMP,TRANSACTION,TRAN,无效,语法错误)

    从SQL SERVER 2008 开始,我们已经不能再用以前 DUMP TRAN 数据库名 WITH NO_LOG 的这种方式来收缩数据库,但是,可以用另外一种替代的方法,SQL语句如下: ALTER ...

随机推荐

  1. 剑指offer 13:数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 保证base和exponent不同时为0   问题分析 计算一个浮点数的整数次 ...

  2. cluster集群基本概念

    cluster集群种类: 1,LB(Load Balance)负载均衡集群: 弱点:当横向扩展到一定机器后,发现在怎么横向加机器也没有效果的时候,瓶颈就卡在分发的服务器上了,也就是LB机器上了,如何解 ...

  3. 执行DOS命令并返回结果

    public static String excuteCommand(String command){ Runtime runtime = Runtime.getRuntime(); try { Pr ...

  4. ACM-求质因数

    求输入数字的所有质因数,并将所有质因数进行排序,并以质因数+空格的形式输出 #include <iostream> #include <string> #include < ...

  5. 201871010111-刘佳华《面向对象程序设计(java)》第七周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第七周学习总结 实验时间 2019-10-11 1.实验目的与要求 1) 掌握四种访问权限修饰符的使用特点: (1)进一步理 ...

  6. Testng 简介

    Testng是一套开源测试框架,是从Junit继承而来,testng意为test next generation,主要有以下特性: annotations  注释,如 @test @BeforeMet ...

  7. Springboot上传图片并访问

    Springboot上传图片并访问 步骤 配置绝对路径,并将这个绝对路径添加到springboot静态资源目录中. 文件上传使用绝对路径保存.返回web相对路径,前端加上域名和项目路径,生成完整的路径 ...

  8. Python接口自动化测试框架实战 从设计到开发

    第1章 课程介绍(不要错过)本章主要讲解课程的详细安排.课程学习要求.课程面向用户等,让大家很直观的对课程有整体认知! 第2章 接口测试工具Fiddler的运用本章重点讲解如何抓app\web的htt ...

  9. 【2019.8.11上午 慈溪模拟赛 T3】欢迎回来(back)(设阈值+莫队)

    设阈值 考虑对于询问的\(d\)设阈值进行分别处理. 对于\(d\le\sqrt{max\ d}\)的询问,我们可以\(O(n\sqrt{max\ d})\)预处理答案,\(O(1)\)输出. 对于\ ...

  10. 【转】 AOP(面向切面编程)、Filter(过虑器)、Interceptor(拦截器)

    AOP(面向切面编程) 面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承.多态和封装.而封装就要求将功能分散到不同的对象中去,这在软 ...