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

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. NSURLSession的知识小记

    1.NSURLSession的使用流程 使用NSRULSession对象创建Task, 然后执行Task 2.获取NSURLSession ()获得共享的Session + (NSURLSession ...

  2. if语句,if...else语句的分析

    if语句的反汇编判断 if语句的反汇编判断基本是围绕JCC指令的,如果想要有深刻的理解,可以自行练习JCC指令 执行各类影响标志位的指令 jxx xxxx 1.案例一 mov eax,dword pt ...

  3. GIL全局解释器锁、死锁、递归锁、线程队列

    目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...

  4. Linux—使用man命令:man:command not found

    # 用echo $PATH查看该环境变量.这种问题一般是环境变量PATH不对的问题. [root@localhost ~]# echo $PATH # 用whereis命令查看,该指令的位置. [ro ...

  5. 网页解析 -- bs4 和 xpath 的简单使用

    bs4 BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库,它的使用方式相对于正则来说更加的简单方便 中文文档:https://beautifulsoup.read ...

  6. Linux中的文件和目录结构详解

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  7. [视频教程] ubuntu系统下以守护进程方式安装使用Redis

    直接访问redis的中国官网,在下载部分,可以看到安装和使用的方式.wget http://download.redis.io/releases/redis-5.0.4.tar.gztar xzf r ...

  8. MASK-RCNN(1)

    MASK-RCNN是一个多用途的网络,可以用来做目标检测,实例分割或者人体姿态识别.主要结构如下. 简单的说,就是首先用Faster-RCNN获得ROI,再进行ROI Align,然后输出ROI的分类 ...

  9. 2015年蓝桥杯B组C/C++决赛题解

    2015年第六届蓝桥杯B组C/C++决赛题解 点击查看2015年第六届蓝桥杯B组C/C++国赛题目(不含答案)     1.积分之迷 三重循环 枚举A,B,C的值,如果满足两个条件:3个A + 7个B ...

  10. Word论文

    粘贴图片不完整,只显示一行? 问题:行距被固定了 临时解决:设置多倍行距,推荐值1.5 1. 点一下图片,然后选择样式-正文 即可, 2. 或者为图片创建专用样式,需要时就点一下: 开始-样式(点样式 ...