事务是SQL中的单个逻辑工作单元,一个事务里的所有语句被作为整体执行
遇到错误时,可以回滚事务内的所有改变,从而保证数据库的一致性和可恢复性
一个逻辑工作单元必须具有四种属性,也称为ACID
·事务的四种属性
1)原子性(Atomicity):一个事物必须作为工作的原子单位,它所做的数据修改要么全部执行,要么全部取消
2)一致性(Consistency):当事务完成后,所有数据必须处于一致状态,即:事务所修改的数据必须遵循数据库中各种约束、规则要求,保持数据的完整性
3)隔离性(Isolation):一个事务所做的修改必须能够与其他事务所作的修改隔离开来;在并发处理过程中,一个事物所看到的数据状态必须为另一个事务处理前或后的数据
4)永久性(Durability):事务完成后,它对数据库所做的修改被永久保留下来。事务日志保证事务的永久性
·事务的分类
1)显示事务:由用户执行T-SQL事务语句而定义的事务,又称为用户定义事务
2)隐士事务:当前事务提交或回滚后,SQL自动开始的事务。使用inplicit_transations选项打开隐士事务。
3)自动事务模式:在自动事务模式下,当一个语句被成功执行后,它被自动提交,而当它执行过程中产生错误事,则被自动回滚。自动事务模式是SQL单位默认管理模式
·举例:
------数据库中的事务
银行转账: 李四转500给张三
BEGIN
DECLARE @AccountMoney1 int;
DECLARE @AccountMoney2 int;
SET @AccountMoney1=0;
SET @AccountMoney2=0;
BEGIN TRAN --定义事物
UPDATE TEST
SET @AccountMoney1=AccountMoney=AccountMoney+500
WHERE AcountName='张三'
UPDATE TEST
SET @AccountMoney2=AccountMoney=AccountMoney-500
WHERE AcountName='李四'
PRINT @AccountMoney1;
PRINT @AccountMoney2;
IF(@AccountMoney1=@AccountMoney2)
COMMIT TRAN --提交事物
ELSE
ROLLBACK TRAN --回滚事物
END
-----------------------C#中的事务
/// <summary>
/// 本地事物
/// </summary>
public void LocaltionTransactionDemo()
{
int intResult = 0;
string strCon = "Data Source=.;Initial Catalog=DB_TRANS;Integrated Security=True";
string strSQL = @"UPDATE TEST
SET AccountMoney=AccountMoney+500
WHERE AcountName='张三'
UPDATE TEST
SET AccountMoney=AccountMoney-500
WHERE AcountName='李四'";
using (SqlConnection con = new SqlConnection(strCon))
{
con.Open();
SqlTransaction st = con.BeginTransaction(); //定义事物
SqlCommand com = new SqlCommand(strSQL, con);
com.Transaction = st; //事物赋值给SqlCommand
try
{
intResult = com.ExecuteNonQuery();
st.Commit(); //提交事物
}
catch (Exception e1)
{
st.Rollback(); //回滚事物
}
}
Console.WriteLine("执行影响的行数: {0}",intResult);
}
public void Demo1()
{
int intResult = 0;
string strCon = "Data Source=.;Initial Catalog=DB_TRANS;Integrated Security=True";
string strSQL = @"UPDATE TEST
SET AccountMoney=AccountMoney+500
WHERE AcountName='张三'";
using (SqlConnection con = new SqlConnection(strCon))
{
con.Open();
SqlCommand com = new SqlCommand(strSQL, con);
intResult = com.ExecuteNonQuery();
}
Console.WriteLine("执行影响的行数: {0}", intResult);
}
public void Demo2()
{
int intResult = 0;
string strCon = "Data Source=.;Initial Catalog=DB_TRANS;Integrated Security=True";
string strSQL = @"UPDATE TEST
SET AccountMoney=AccountMoney-500
WHERE AcountName='李四'";
using (SqlConnection con = new SqlConnection(strCon))
{
con.Open();
SqlCommand com = new SqlCommand(strSQL, con);
intResult = com.ExecuteNonQuery();
}
Console.WriteLine("执行影响的行数: {0}", intResult);
}
/// <summary>
/// 分布式事物
/// </summary>
public void DistributeTransactionDemo()
{
using(TransactionScope ts=new TransactionScope(TransactionScopeOption.Required))
{
this.Demo1();
this.Demo2();
ts.Complete(); //事物提交
}
}