做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线、真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程(存储过程加事务),完成了一个功能的实现就万事大吉了,这次想换一种新的方法:经过和师哥的交流学习,在代码中使用事务同样也是可以解决问题的,可以保证数据的正确性,就像银行取款一样,如果在取款的过程中取款机出现故障,我们个人的账户上的金额不会受任何影响等。

代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作。

首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一个连接、事务完成关闭同一个连接的一个共有类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Maticsoft.DBUtility;
namespace PersonalFiles.DAL
{
public class DBTransaction
{
private DbHelperSQL SqlHelper = null; public DBTransaction()
{
SqlHelper = new DbHelperSQL();
} /// <summary>
/// 获取数据库连接
/// </summary>
/// <returns></returns>
public SqlConnection GetConnection()
{
return SqlHelper.GetCon();
} /// <summary>
/// 获取事务
/// </summary>
/// <returns></returns>
public SqlTransaction GetTransaction(SqlConnection conn)
{
return conn.BeginTransaction();
} /// <summary>
/// 提交事务
/// </summary>
public void Commit(SqlTransaction sqlTransaction)
{
sqlTransaction.Commit();
} /// <summary>
/// 回滚事务
/// </summary>
public void Rollback(SqlTransaction sqlTransaction)
{
sqlTransaction.Rollback();
} /// <summary>
/// 关闭连接
/// </summary>
public void Close(SqlConnection conn)
{ if (conn.State == ConnectionState.Open)
{
conn.Close();
} }
}
}

界面层的后台代码和以前一样直接调去就行了,现在来看主要是在B层中的代码发生了很大的变化,需要向下层传递事务与获取的连接

/// <summary>
/// 增加一条数据
/// </summary>
public void Add(PersonalFiles.Model.BasicInformation modelBasic, PersonalFiles.Model.T_HumanAgency model)
{
int flag = 0; DBTransaction DbTran = new DBTransaction(); //获得连接
SqlConnection conn = DbTran.GetConnection(); //开启事务
SqlTransaction trans = DbTran.GetTransaction(conn);
try
{
//把获得的同一个连接与事务一共传下去
//dalBasic.Add(modelBasic,conn,trans); //把获得的同一个连接与事务一共传下去 dalAgency.Add(model,conn,trans); //事务提交
DbTran.Commit(trans);
//return true;
} catch (Exception ex)
{
//回滚事务
DbTran.Rollback(trans);
}
finally
{
DbTran.Close(conn);
}
}

注意的是向D层传是我们需要传的是B层获取的同一个连接于开启的是一个事务:

/// <summary>
/// 增加一条数据
/// </summary>
public void Add(PersonalFiles.Model.T_HumanAgency model,SqlConnection conn,SqlTransaction trans)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("insert into T_HumanAgency(");
strSql.Append("myidentity,relation,receivemode,workingtime,intotime,oldworkplace,nowworkplace,inervice,registered,registeredcardid,registeredid,householder,isrecord,fileintotime,fileouttime,filetowhere,relationouttime,Paymentstandard,paymentsmonth,payments,stoptime,state,pri,admin,ID)");
strSql.Append(" values (");
strSql.Append("@myidentity,@relation,@receivemode,@workingtime,@intotime,@oldworkplace,@nowworkplace,@inervice,@registered,@registeredcardid,@registeredid,@householder,@isrecord,@fileintotime,@fileouttime,@filetowhere,@relationouttime,@Paymentstandard,@paymentsmonth,@payments,@stoptime,@state,@pri,@admin,@ID)");
SqlParameter[] parameters = {
new SqlParameter("@myidentity", SqlDbType.VarChar,50),
new SqlParameter("@relation", SqlDbType.VarChar,50),
new SqlParameter("@receivemode", SqlDbType.VarChar,50),
new SqlParameter("@workingtime", SqlDbType.VarChar,50),
new SqlParameter("@intotime", SqlDbType.VarChar,50),
new SqlParameter("@oldworkplace", SqlDbType.VarChar,50),
new SqlParameter("@nowworkplace", SqlDbType.VarChar,50),
new SqlParameter("@inervice", SqlDbType.VarChar,50),
new SqlParameter("@registered", SqlDbType.VarChar,50),
new SqlParameter("@registeredcardid", SqlDbType.VarChar,50),
new SqlParameter("@registeredid", SqlDbType.VarChar,50),
new SqlParameter("@householder", SqlDbType.VarChar,50),
new SqlParameter("@isrecord", SqlDbType.VarChar,50),
new SqlParameter("@fileintotime", SqlDbType.VarChar,50),
new SqlParameter("@fileouttime", SqlDbType.VarChar,50),
new SqlParameter("@filetowhere", SqlDbType.VarChar,50),
new SqlParameter("@relationouttime", SqlDbType.VarChar,50),
new SqlParameter("@Paymentstandard", SqlDbType.VarChar,50),
new SqlParameter("@paymentsmonth", SqlDbType.VarChar,50),
new SqlParameter("@payments", SqlDbType.VarChar,50),
new SqlParameter("@stoptime", SqlDbType.VarChar,50),
new SqlParameter("@state", SqlDbType.VarChar,50),
new SqlParameter("@admin", SqlDbType.VarChar,50),
new SqlParameter("@pri", SqlDbType.VarChar,50),
new SqlParameter("@ID", SqlDbType.VarChar,50)};
parameters[0].Value = model.myidentity;
parameters[1].Value = model.relation;
parameters[2].Value = model.receivemode;
parameters[3].Value = model.workingtime;
parameters[4].Value = model.intotime;
parameters[5].Value = model.oldworkplace;
parameters[6].Value = model.nowworkplace;
parameters[7].Value = model.inervice;
parameters[8].Value = model.registered;
parameters[9].Value = model.registeredcardid;
parameters[10].Value = model.registeredid;
parameters[11].Value = model.householder;
parameters[12].Value = model.isrecord;
parameters[13].Value = model.fileintotime;
parameters[14].Value = model.fileouttime;
parameters[15].Value = model.filetowhere;
parameters[16].Value = model.relationouttime;
parameters[17].Value = model.Paymentstandard;
parameters[18].Value = model.paymentsmonth;
parameters[19].Value = model.payments;
parameters[20].Value = model.stoptime;
parameters[21].Value = model.state;
parameters[22].Value = model.pri;
parameters[23].Value = model.admin;
parameters[24].Value = model.ID; //DbHelperSQL.ExecuteSql(strSql.ToString(), parameters);
DbHelperSQL.ExecuteSql(strSql.ToString(),conn,trans, parameters);
}

在代码中添加事务与存储过程中添加事务的异同

相同点

1:都能够保证数据的一致性。

不同点:

1:代码中添加事务的好处是:增加了代码的可读性、与可维护性,方便后期人员维护系统看代码能够一目了然的看懂代码,而在数据库中添加存储过程的可读性不是很好。

2:为什么不建议使用数据库自带的存储过程+事务呢?主要是一个项目过多的依赖数据库,这样对后期的数据库迁移都会带来一定的影响与不便(sql向oracle迁移),好多转换不是很容易兼容性和不是很好(以后再深入学习)。

3:合作开发时如果是代码中添加事务遵循了代码上传的原则,这样方便大家的交流。

为什么使用事务可以保证同一个连接向数据库多个表写信息的正确性与一致性的原理:

事务的原子性

事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据改操作要全部执行,要么全部不执行。这种特性称为原子性。  事务的原子性要求,如果把一个事务看作是一个程序,它要么完整的被执行,要么完全执行。就是说事务的操纵序列或者完全应用到数据库或者完全不影响数据库。这种特性称为原则性  假如用户在一个事务内完成了对数据库的更新,这时所有的更新对外部世界必须是可见的,或者完全没有更新。前者称事务已提交,后者称事务撤销。DBMS必须确保由成功提交的事物完成的所有操作在数据库内有完全的反映,而失败的事务对数据库完全没有影响

事务的隔离性

事务开始执行了但是没有提交事务,数据并没有真正的写到数据库里面,当我去断点测试的时候当第一个程序向数据库发出写完时,我去查找数据库不能打开数据库,不能查找,提示连接超时,由于事务的隔离性,数据并没有真正的写到数据库里面,等事务提交才可以查到数据库,可见同一个连接下执行的程序在同一个事务执行的开始于结束后才真正写到数据库里面,如果过程当中保存事务回滚,数据不会写到数据库里面。保证数据的一致性与正确性。

数据的准确性与一致性是我们要时刻考虑的,一个好的系统必须有较好的准确性才能保证用户的使用。

代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性的更多相关文章

  1. 在易语言中调用MS SQL SERVER数据库存储过程方法总结

    Microsoft SQL SERVER 数据库存储过程,根据其输入输出数据,笼统的可以分为以下几种情况或其组合:无输入,有一个或多个输入参数,无输出,直接返回(return)一个值,通过output ...

  2. Ado.Net实体数据模型EF,如何在代码中添加数据库连接密码

    在创建EF模型的时候,VS2013提示说“在连接字符串中存储敏感数据可能有安全风险”,于是我选择了在代码中添加,可是如何通过代码添加呢? 我在网上百度了下,没有人说的清楚直观. 假设我们创建了一个名字 ...

  3. 移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签)

    移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签) 一.总结 一句话总结: 添加viewport标签:meta name="viewport" ...

  4. MySQL--视图view、触发器trigger、事务(start transaction)、存储过程(特殊的数据逻辑处理函数)、流程控制(if,case....)

    mysql致力于项目开发及数据库管理之间解耦合(帮忙封装一些数据处理方法,使应用程序的开发者可以专注于应用程序的开发),但受限于不同部门沟通的成本问题,现阶段直接使用的价值不大. 一.视图(只能sel ...

  5. springmvc 事务控制与数据库隔离级别

    springmvc 事物传播与数据库隔离控制 http://www.cnblogs.com/yangy608/archive/2011/06/29/2093478.html 一.Propagation ...

  6. unity中添加音量控制的一些步骤

    1.先确认要控制的音源(Audio Source)所使用的输出(Output),例如我这里BGM使用的是MainMixer: 2.暴露音量(Volume)参数,让脚本可以控制.这里如果不暴露出来,脚本 ...

  7. (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。

    在使用 Unity3d 倒入Fbx模型的时候,动画的动画片段需要自己手动添加模型多了以后会是一个不小的工作量. Unity3d支持 编辑器脚本来控制资源导入的过程.添加一个 AssetPostproc ...

  8. 如何优雅的在 vue 中添加权限控制

    前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...

  9. 如何在 vue 中添加权限控制管理?---vue中文社区

    前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...

随机推荐

  1. windows程序设计读书笔记4——字符显示3

    在之前的一章里我们使用InvalidateRect函数,生成窗口重绘消息进行重绘,但是并没有在处理滚动条消息时直接绘制,这样的代码效率并不高. 这里作者使用了UpdateWindow函数,直接进行窗口 ...

  2. 动态创建分页 LINQ+EF

    public class Message { public int MessageId { get; set; } public string MessageTitle { get; set; } p ...

  3. Git 操作常用命令

    Git使用 1. git pull    更新服务器代码到本地a). git pull origin master是将origin这个版本库的代码更新到本地的master主分支 2. git push ...

  4. fieldset 使用小案例

    有初学者问到如何做出如下页面: 对应的代码如下: <fieldset> <legend>★审核状态</legend> <input name="st ...

  5. OS X 键盘快捷键

    了解有关常见 OS X 键盘快捷键的信息.键盘快捷键是通过按下键盘上的组合键来调用 OS X 功能的一种方式. 若要使用键盘快捷键或按键组合,您可以同时按修饰键和字符键.例如,同时按下 Command ...

  6. C语言入门(17)——C语言数组应用的一个实例

    本篇通过一个实例介绍使用数组的一些基本模式.问题是这样的:首先生成一列0-9的随机数保存在数组中,然后统计其中每个数字出现的次数并打印,检查这些数字的随机性如何.随机数在某些场合(例如游戏程序)中是非 ...

  7. ESMOD北京高级时装艺术学校_百度百科

    ESMOD北京高级时装艺术学校_百度百科 ESMOD北京高级时装艺术学校

  8. action中实现对批量文件上传的封装

    如今,文件(尤其是图片)上传,在前后台的应用相当普遍,上传头像.共享资料等已成为最基本应用.我们很希望通过一个万能的封装方法来实现一劳永逸的效果. 接下来,就来为大家介绍具体实现. 首先,我们需要一个 ...

  9. Linux学习十八之、善用判断式

    原文地址:http://vbird.dic.ksu.edu.tw/linux_basic/0340bashshell-scripts_3.php 善用判断式 在第十一章中,我们提到过 $? 这个变量所 ...

  10. 浅谈hadoop中mapreduce的文件分发

    近期在做数据分析的时候.须要在mapreduce中调用c语言写的接口.此时就须要把动态链接库so文件分发到hadoop的各个节点上,原来想自己来做这个分发,大概过程就是把so文件放在hdfs上面,然后 ...