sql 数据库事务详解

sql 数据库教程事务详解

作为大型的企业级数据库,SQL Server2000对事务提供了很好的支持。我们可以使用SQL语句来定义、提交以及回滚一个事务。

??如下所示的SQL代码定义了一个事务,并且命名为"MyTransaction"(限于篇幅,本文并不讨论如何编写SQL语言程序,请读者自行参考相关书籍):

DECLARE @TranName VARCHAR(20)

SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranNameGOUSE pubs
GO

UPDATE roysched
SET royalty = royalty * 1.10
WHERE title_id LIKE 'Pc%'
GO

COMMIT TRANSACTION MyTransaction
GO
 

??这里用到了SQL Server2000自带的示例数据库pubs,提交事务后,将为所有畅销计算机书籍支付的版税增加 10%。

??打开SQL Server2000的查询分析器,选择pubs数据库,然后运行这段程序,结果显而易见。

??可是如何在C#程序中运行呢?我们记得在普通的SQL查询中,一般需要把查询语句赋值给SalCommand.CommandText属性,这里也就像普通的SQL查询语句一样,将这些语句赋给SqlCommand.CommandText属性即可。要注意的一点是,其中的"GO"语句标志着SQL批处理的结束,编写SQL脚本是需要的,但是在这里是不必要的。我们可以编写如下的程序来验证这个想法:

//TranSql.csusing System;
using System.Data;
using System.Data.SqlClient;
namespace Aspcn
{
 public class DbTranSql
 {
  file://将事务放到SQL Server中执行
  public void DoTran()
  {
   file://建立连接并打开
   SqlConnection myConn=GetConn();myConn.Open();
   SqlCommand myComm=new SqlCommand();
   try
   {
    myComm.Connection=myConn;
    myComm.CommandText="DECLARE @TranName VARCHAR(20) ";
    myComm.CommandText+="SELECT @TranName = 'MyTransaction' ";
    myComm.CommandText+="BEGIN TRANSACTION @TranName ";
    myComm.CommandText+="USE pubs ";
    myComm.CommandText+="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%' ";
    myComm.CommandText+="COMMIT TRANSACTION MyTransaction ";
    myComm.ExecuteNonQuery();
   }
   catch(Exception err)
   {
    throw new ApplicationException("事务操作出错,系统信息:"+err.Message);
   }
   finally
   {
    myConn.Close();
   }
  }
  file://获取数据连接
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }

 public class Test
 {
  public static void Main()
  {
   DbTranSql tranTest=new DbTranSql();
   tranTest.DoTran();
   Console.WriteLine("事务处理已经成功完成。");
   Console.ReadLine();
  }
 }
}
 

 

  注意到其中的SqlCommand对象myComm,它的CommandText属性仅仅是前面SQL代码字符串连接起来即可,当然,其中的"GO"语句已经全部去掉了。这个语句就像普通的查询一样,程序将SQL文本事实上提交给DBMS去处理了,然后接收返回的结果(如果有结果返回的话)。

??很自然,我们最后看到了输出"事务处理已经成功完成",再用企业管理器查看pubs数据库的roysched表,所有title_id字段以"PC"开头的书籍的royalty字段的值都增加了0.1倍。

??这里,我们并没有使用ADO.net的事务处理机制,而是简单地将执行事务的SQL语句当作普通的查询来执行,因此,事实上该事务完全没有用到.net的相关特性。
了解.net中的事务机制

??如你所知,在.net框架中主要有两个命名空间(namespace)用于应用程序同数据库系统的交互:System.Data.SqlClient和System.Data.OleDb。前者专门用于连接Microsoft公司自己的SQL Server数据库,而后者可以适应多种不同的数据库。这两个命名空间中都包含有专门用于管理数据库事务的类,分别是System.Data.SqlClient.SqlTranscation类和System.Data.OleDb.OleDbTranscation类。

??就像它们的名字一样,这两个类大部分功能是一样的,二者之间的主要差别在于它们的连接机制,前者提供一组直接调用 SQL Server 的对象,而后者使用本机 OLE DB 启用数据访问。事实上,ADO.net 事务完全在数据库的内部处理,且不受 Microsoft 分布式事务处理协调器 (DTC) 或任何其他事务性机制的支持。本文将主要介绍System.Data.SqlClient.SqlTranscation类,下面的段落中,除了特别注明,都将使用System.Data.SqlClient.SqlTranscation类。??

 

事务的开启和提交
??现在我们对事务的概念和原理都了然于心了,并且作为已经有一些基础的C#开发者,我们已经熟知编写数据库交互程序的一些要点,即使用SqlConnection类的对象的Open()方法建立与数据库服务器的连接,然后将该连接赋给SqlCommand对象的Connection属性,将欲执行的SQL语句赋给它的CommandText属性,于是就可以通过SqlCommand对象进行数据库操作了。对于我们将要编写的事务处理程序,当然还需要定义一个SqlTransaction类型的对象。并且看到SqlCommand对象的Transcation属性,我们很容易想到新建的SqlTransaction对象应该与它关联起来。

基于以上认识,下面我们就开始动手写我们的第一个事务处理程序。我们可以很熟练地写出下面这一段程序:

//DoTran.csusing System;
using System.Data;
using System.Data.SqlClient;
namespace Aspcn
{
 public class DbTran
 {
  file://执行事务处理
  public void DoTran()
  {
   file://建立连接并打开
   SqlConnection myConn=GetConn();
   myConn.Open();
   SqlCommand myComm=new SqlCommand();
   SqlTransaction myTran=new SqlTransaction();
   try
   {
    myComm.Connection=myConn;
    myComm.Transaction=myTran;
   
    file://定位到pubs数据库 
    myComm.CommandText="USE pubs";
    myComm.ExecuteNonQuery();

    file://更新数据
    file://将所有的计算机类图书
    myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'";
    myComm.ExecuteNonQuery();//提交事务
    myTran.Commit();
   }
   catch(Exception err)
   {
    throw new ApplicationException("事务操作出错,系统信息:"+err.Message);
   }
   finally
   {
    myConn.Close();
   }
  }
  file://获取数据连接
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }

 public class Test{public static void Main()
 {
  DbTran tranTest=new DbTran();
  tranTest.DoTran();
  Console.WriteLine("事务处理已经成功完成。");
  Console.ReadLine();
 }
}
}
 

??显然,这个程序非常简单,我们非常自信地编译它,但是,出乎意料的结果使我们的成就感顿时烟消云散:??error CS1501: 重载"SqlTransaction"方法未获取"0"参数

??是什么原因呢?注意到我们初始化的代码:

SqlTransaction myTran=new SqlTransaction();
 

??显然,问题出在这里,事实上,SqlTransaction类并没有公共的构造函数,我们不能这样新建一个SqlTrancaction类型的变量。在事务处理之前确实需要有一个SqlTransaction类型的变量,将该变量关联到SqlCommand类的Transcation属性也是必要的,但是初始化方法却比较特别一点。在初始化SqlTransaction类时,你需要使用SqlConnection类的BeginTranscation()方法:

SqlTransaction myTran; myTran=myConn.BeginTransaction();
 

??该方法返回一个SqlTransaction类型的变量。在调用BeginTransaction()方法以后,所有基于该数据连接对象的SQL语句执行动作都将被认为是事务MyTran的一部分。同时,你也可以在该方法的参数中指定事务隔离级别和事务名称,如:

SqlTransaction myTran;
myTran=myConn.BeginTransaction(IsolationLevel.ReadCommitted,"SampleTransaction");
 

  关于隔离级别的概念我们将在随后的内容中探讨,在这里我们只需牢记一个事务是如何被启动,并且关联到特定的数据链接的。
??先不要急着去搞懂我们的事务都干了些什么,看到这一行:

myTran.Commit();
 

??是的,这就是事务的提交方式。该语句执行后,事务的所有数据库操作将生效,并且为数据库事务的持久性机制所保持--即使系统在这以后发生致命错误,该事务对数据库的影响也不会消失。

??对上面的程序做了修改之后我们可以得到如下代码(为了节约篇幅,重复之处已省略,请参照前文):

//DoTran.cs……}

file://执行事务处理
public void DoTran()
{
 file://建立连接并打开
 SqlConnection myConn=GetConn();
 myConn.Open();
 SqlCommand myComm=new SqlCommand();

 file://SqlTransaction myTran=new SqlTransaction();
 file://注意,SqlTransaction类无公开的构造函数

 SqlTransaction myTran;

 file://创建一个事务
 myTran=myConn.BeginTransaction();
 try
 {
  file://从此开始,基于该连接的数据操作都被认为是事务的一部分
  file://下面绑定连接和事务对象
  myComm.Connection=myConn;
  myComm.Transaction=myTran; file://定位到pubs数据库
  myComm.CommandText="USE pubs";
  myComm.ExecuteNonQuery();//更新数据
  file://将所有的计算机类图书
  myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'";
  myComm.ExecuteNonQuery();
 
  file://提交事务
  myTran.Commit();
 }
 catch(Exception err)
 {
  throw new ApplicationException("事务操作出错,系统信息:"+err.Message);
  }
 finally
 {
  myConn.Close();
  }
}
……
 

??到此为止,我们仅仅掌握了如何开始和提交事务。下一步我们必须考虑的是在事务中可以干什么和不可以干什么。

另一个走向极端的错误
??满怀信心的新手们可能为自己所掌握的部分知识陶醉不已,刚接触数据库库事务处理的准开发者们也一样,踌躇满志地准备将事务机制应用到他的数据处理程序的每一个模块每一条语句中去。的确,事务机制看起来是如此的诱人——简洁、美妙而又实用,我当然想用它来避免一切可能出现的错误——我甚至想用事务把我的数据操作从头到尾包裹起来。
??看着吧,下面我要从创建一个数据库开始:

using System;
using System.Data;
using System.Data.SqlClient;

namespace Aspcn
{
 public class DbTran
 {
  file://执行事务处理
  public void DoTran()
  {
   file://建立连接并打开
   SqlConnection myConn=GetConn();
   myConn.Open();

   SqlCommand myComm=new SqlCommand();
   SqlTransaction myTran;

   myTran=myConn.BeginTransaction();

   file://下面绑定连接和事务对象
   myComm.Connection=myConn;
   myComm.Transaction=myTran;

   file://试图创建数据库TestDB
   myComm.CommandText="CREATE database TestDB";
   myComm.ExecuteNonQuery();

   file://提交事务
   myTran.Commit();
  }

  file://获取数据连接
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }

 public class Test
 {
  public static void Main()
  {
   DbTran tranTest=new DbTran();
   tranTest.DoTran();
   Console.WriteLine("事务处理已经成功完成。");
   Console.ReadLine();
  }
 }
}

??//---------------
 

  未处理的异常: System.Data.SqlClient.SqlException: 在多语句事务内不允许使用 CREATE DATABASE 语句。

at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Aspcn.DbTran.DoTran()
at Aspcn.Test.Main()
 

??注意,如下的SQL语句不允许出现在事务中:

ALTER DATABASE
 修改数据库
 
BACKUP LOG
 备份日志
 
CREATE DATABASE
 创建数据库
 
DISK INIT
 创建数据库或事务日志设备
 
DROP DATABASE
 删除数据库
 
DUMP TRANSACTION
 转储事务日志
 
LOAD DATABASE
 装载数据库备份复本
 
LOAD TRANSACTION
 装载事务日志备份复本
 
RECONFIGURE
 更新使用 sp_configure 系统存储过程更改的配置选项的当前配置(sp_configure 结果集中的 config_value 列)值。
 
RESTORE DATABASE
 还原使用BACKUP命令所作的数据库备份
 
RESTORE LOG
 还原使用BACKUP命令所作的日志备份
 
UPDATE STATISTICS
 在指定的表或索引视图中,对一个或多个统计组(集合)有关键值分发的信息进行更新
 

??除了这些语句以外,你可以在你的数据库事务中使用任何合法的SQL语句。

事务回滚
??事务的四个特性之一是原子性,其含义是指对于特定操作序列组成的事务,要么全部完成,要么就一件也不做。如果在事务处理的过程中,发生未知的不可预料的错误,如何保证事务的原子性呢?当事务中止时,必须执行回滚操作,以便消除已经执行的操作对数据库的影响。
??一般的情况下,在异常处理中使用回滚动作是比较好的想法。前面,我们已经得到了一个更新数据库的程序,并且验证了它的正确性,稍微修改一下,可以得到:

//RollBack.cs
using System;
using System.Data;
using System.Data.SqlClient;

namespace Aspcn
{
 public class DbTran
 {
  file://执行事务处理
  public void DoTran()
  {
   file://建立连接并打开
   SqlConnection myConn=GetConn();
   myConn.Open();

   SqlCommand myComm=new SqlCommand();
   SqlTransaction myTran;

   file://创建一个事务
   myTran=myConn.BeginTransaction();
   file://从此开始,基于该连接的数据操作都被认为是事务的一部分
   file://下面绑定连接和事务对象
   myComm.Connection=myConn;
   myComm.Transaction=myTran;

   try
   {
    file://定位到pubs数据库
    myComm.CommandText="USE pubs";
    myComm.ExecuteNonQuery();
   
    myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'";
    myComm.ExecuteNonQuery();

    file://下面使用创建数据库的语句制造一个错误
    myComm.CommandText="Create database testdb";
    myComm.ExecuteNonQuery();

    myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.20 WHERE title_id LIKE 'Ps%'";
    myComm.ExecuteNonQuery();

    file://提交事务
    myTran.Commit();
   }
   catch(Exception err)
   {
    myTran.Rollback();
    Console.Write("事务操作出错,已回滚。系统信息:"+err.Message);
   }
  }

  file://获取数据连接
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }
 public class Test
 {
  public static void Main()
  {
   DbTran tranTest=new DbTran();
   tranTest.DoTran();
   Console.WriteLine("事务处理已经成功完成。");
   Console.ReadLine();
  }
 }
}
 

??首先,我们在中间人为地制造了一个错误——使用前面讲过的Create database语句。然后,在异常处理的catch块中有如下语句:

 

myTran.Rollback();

 

??当异常发生时,程序执行流跳转到catch块中,首先执行的就是这条语句,它将当前事务回滚。在这段程序可以看出,在Create database之前,已经有了一个更新数据库的操作——将pubs数据库的roysched表中的所有title_id字段以“PC”开头的书籍的royalty字段的值都增加0.1倍。但是,由于异常发生而导致的回滚使得对于数据库来说什么都没有发生。由此可见,Rollback()方法维护了数据库的一致性及事务的原子性。

使用存储点

??事务只是一种最坏情况下的保障措施,事实上,平时系统的运行可靠性都是相当高的,错误很少发生,因此,在每次事务执行之前都检查其有效性显得代价太高——绝大多数的情况下这种耗时的检查是不必要的。我们不得不想另外一种办法来提高效率。

??事务存储点提供了一种机制,用于回滚部分事务。因此,我们可以不必在更新之前检查更新的有效性,而是预设一个存储点,在更新之后,如果没有出现错误,就继续执行,否则回滚到更新之前的存储点。存储点的作用就在于此。要注意的是,更新和回滚代价很大,只有在遇到错误的可能性很小,而且预先检查更新的有效性的代价相对很高的情况下,使用存储点才会非常有效。

??使用.net框架编程时,你可以非常简单地定义事务存储点和回滚到特定的存储点。下面的语句定义了一个存储点“NoUpdate”:

 

myTran.Save("NoUpdate");

 

当你在程序中创建同名的存储点时,新创建的存储点将替代原有的存储点。

在回滚事务时,只需使用Rollback()方法的一个重载函数即可:

 

myTran.Rollback("NoUpdate");

 

下面这段程序说明了回滚到存储点的方法和时机:

using System;
using System.Data;
using System.Data.SqlClient;

namespace Aspcn
{
 public class DbTran
 { 
  file://执行事务处理
  public void DoTran()
  {
   file://建立连接并打开
   SqlConnection myConn=GetConn();
   myConn.Open();

   SqlCommand myComm=new SqlCommand();
   SqlTransaction myTran;

   file://创建一个事务
   myTran=myConn.BeginTransaction();
   file://从此开始,基于该连接的数据操作都被认为是事务的一部分
   file://下面绑定连接和事务对象
   myComm.Connection=myConn;
   myComm.Transaction=myTran;

   try
   {
    myComm.CommandText="use pubs";
    myComm.ExecuteNonQuery();

    myTran.Save("NoUpdate");

    myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'";
    myComm.ExecuteNonQuery();

    file://提交事务
    myTran.Commit();
   }
   catch(Exception err)
   {
    file://更新错误,回滚到指定存储点
    myTran.Rollback("NoUpdate");
    throw new ApplicationException("事务操作出错,系统信息:"+err.Message);
   }
  }

  file://获取数据连接
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }
 public class Test
 {
  public static void Main()
  {
   DbTran tranTest=new DbTran();
   tranTest.DoTran();
   Console.WriteLine("事务处理已经成功完成。");
   Console.ReadLine();
  }
 }
}
 

??很明显,在这个程序中,更新无效的几率是非常小的,而且在更新前验证其有效性的代价相当高,因此我们无须在更新之前验证其有效性,而是结合事务的存储点机制,提供了数据完整性的保证。

隔离级别的概念

??企业级的数据库每一秒钟都可能应付成千上万的并发访问,因而带来了并发控制的问题。由数据库理论可知,由于并发访问,在不可预料的时刻可能引发如下几个可以预料的问题:

  脏读:包含未提交数据的读取。例如,事务1 更改了某行。事务2 在事务1 提交更改之前读取已更改的行。如果事务1 回滚更改,则事务2 便读取了逻辑上从未存在过的行。

  不可重复读取:当某个事务不止一次读取同一行,并且一个单独的事务在两次(或多次)读取之间修改该行时,因为在同一个事务内的多次读取之间修改了该行,所以每次读取都生成不同值,从而引发不一致问题。

  幻象:通过一个任务,在以前由另一个尚未提交其事务的任务读取的行的范围中插入新行或删除现有行。带有未提交事务的任务由于该范围中行数的更改而无法重复其原始读取。

??如你所想,这些情况发生的根本原因都是因为在并发访问的时候,没有一个机制避免交叉存取所造成的。而隔离级别的设置,正是为了避免这些情况的发生。事务准备接受不一致数据的级别称为隔离级别。隔离级别是一个事务必须与其它事务进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较高的隔离级别可以确保数据的正确性,但可能对并发产生负面影响。

??根据隔离级别的不同,DBMS为并行访问提供不同的互斥保证。在SQL Server数据库中,提供四种隔离级别:未提交读、提交读、可重复读、可串行读。这四种隔离级别可以不同程度地保证并发的数据完整性:

隔离级别
 脏读
 不可重复读取
 幻像
 
未提交读
 是
 是
 是
 
提交读
 否
 是
 是
 
可重复读
 否
 否
 是
 
可串行读
 否
 否
 否
 

??可以看出,“可串行读”提供了最高级别的隔离,这时并发事务的执行结果将与串行执行的完全一致。如前所述,最高级别的隔离也就意味着最低程度的并发,因此,在此隔离级别下,数据库的服务效率事实上是比较低的。尽管可串行性对于事务确保数据库中的数据在所有时间内的正确性相当重要,然而许多事务并不总是要求完全的隔离。例如,多个作者工作于同一本书的不同章节。新章节可以在任意时候提交到项目中。但是,对于已经编辑过的章节,没有编辑人员的批准,作者不能对此章节进行任何更改。这样,尽管有未编辑的新章节,但编辑人员仍可以确保在任意时间该书籍项目的正确性。编辑人员可以查看以前编辑的章节以及最近提交的章节。这样,其它的几种隔离级别也有其存在的意义。

??在.net框架中,事务的隔离级别是由枚举System.Data.IsolationLevel所定义的:??

[Flags]
[Serializable]
public enum IsolationLevel
 

??其成员及相应的含义如下:

成员
 含义
 
Chaos
 无法改写隔离级别更高的事务中的挂起的更改。
 
ReadCommitted
 在正在读取数据时保持共享锁,以避免脏读,但是在事务结束之前可以更改数据,从而导致不可重复的读取或幻像数据。
 
ReadUncommitted
 可以进行脏读,意思是说,不发布共享锁,也不接受独占锁。
 
RepeatableRead
 在查询中使用的所有数据上放置锁,以防止其他用户更新这些数据。防止不可重复的读取,但是仍可以有幻像行。
 
Serializable
 在DataSet上放置范围锁,以防止在事务完成之前由其他用户更新行或向数据集中插入行。
 
Unspecified
 正在使用与指定隔离级别不同的隔离级别,但是无法确定该级别。
 

??显而意见,数据库的四个隔离级别在这里都有映射。

??默认的情况下,SQL Server使用ReadCommitted(提交读)隔离级别。

??关于隔离级别的最后一点就是如果你在事务执行的过程中改变了隔离级别,那么后面的命名都在最新的隔离级别下执行——隔离级别的改变是立即生效的。有了这一点,你可以在你的事务中更灵活地使用隔离级别从而达到更高的效率和并发安全性

时间: 2024-09-17 21:16:09

sql 数据库事务详解的相关文章

mysql dba系统学习(22)数据库事务详解

上个星期去面试数据库管理员的工作,笔试通过之后就是直接的面试,他问了我一个问题,叫我介绍哈数据库的事务的看法和理解,但是不知所错的没有章法的乱答一气,唉唉,基础不扎实啊. 下面来好好的学习哈mysqlinnodb引擎的事务相关的知识 一,我们为什么需要数据库事务呢? 这个问题看似很简单,但是真的能够说明白还是要看看我们的基本功是不是扎实 例如,用户A给用户B通过ATM机转账1000元,那么A账户上就会少1000元,而B用户会多1000元 在这个过程中,两个环节是关联的.第一个账户划出款项必须保证

异步的SQL数据库封装详解_MsSql

引言 我一直在寻找一种简单有效的库,它能在简化数据库相关的编程的同时提供一种异步的方法来预防死锁. 我找到的大部分库要么太繁琐,要么灵活性不足,所以我决定自己写个. 使用这个库,你可以轻松地连接到任何 SQL-Server 数据库,执行任何存储过程或 T-SQL 查询,并异步地接收查询结果.这个库采用 C# 开发,没有其他外部依赖. 背景 你可能需要一些事件驱动编程的背景知识,但这不是必需的. 使用 这个库由两个类组成: 1.BLL (Business Logic Layer) 提供访问MS-S

有关jsp在windows下的配置及连接SQLServer数据库的详解

js|server|sqlserver|window|数据|数据库|详解 最近在学习jsp,有关jsp的运行环境的配置问题着实让我费了不少功夫,环境配置好了,连接SQL Sever 2000数据库时又出了不少问题,鉴于此我把自己配置这两方面的详细步骤给大家共享一下,希望刚刚接触jsp的并立志在jsp方面有所成就的同仁少走一些弯路,让我共同进步.有希望与我交流的请加我qq:26544472(在验证信息中请注明jsp交流) (一)有关jsp在windows下的配置: Sun推出的JSP(Java S

如何远程调用Access数据库方法详解

  如何远程调用Access数据库方法详解: 使用了TCP/IP,ADO及XML(需要安装Microsoft XML 4.0.).分服务器和客户端两部分,服务器可以多用户同时连接.远程连接Access数据库有很多方法,我以前已经比较详细的回答过(见下面所列的5种方法),我现在这个例子属于其中的第3种方法(不需要使用RDS或Web服务器). 远程连接access数据库的几个方法: 1.建立VPN(Virtual Private Network),这样你的电脑和主机的连接就与局域网无异,然后把服务器

Java连接操作Oracle数据库代码详解_java

废话不多说了,直接给大家贴关键代码了,具体代码如下所示: package com.sp.test; import java.sql.*; import java.util.*; public class Text_lianxi extends Thread { public void run() { try { yunxing(); Thread.sleep(10000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.pr

Centos 5.2下安装多个mysql数据库配置详解_Mysql

一.编译安装第一个MySQL 5.1.33 cd /opt /usr/sbin/groupadd mysql /usr/sbin/useradd -g mysql mysql -s /bin/nologin -d /usr/local/mysql tar -zxvf mysql-5.1.33.tar.gz cd mysql-5.1.33/ ./configure --prefix=/usr/local/mysql/ --enable-assembler --with-extra-charsets

Android编程操作嵌入式关系型SQLite数据库实例详解_Android

本文实例分析了Android编程操作嵌入式关系型SQLite数据库的方法.分享给大家供大家参考,具体如下: SQLite特点 1.Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型 例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数. 除非是主键被定义为Integer,这时只能存储64位整数 2.创建数据库的表时可以不指定数据类型,例如: 复制代码 代码如下: CREATE TAB

Mysql之SQL Mode用法详解_Mysql

一.Mysql SQL Mode简介 通常来说MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这类模式定义了MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查.这样,就能在众多不同的环境下.与其他数据库服务器一起更容易地使用MySQL.可以使用"--sql-mode="modes""选项,通过启动mysqld来设置默认的SQL模式.而从MySQL 4.

sql 触发器操作详解

触发器对表进行插入.更新.删除的时候会自动执行的特殊存储过程.触发器一般用在check约束更加复杂的约束上面.触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作.诸如:update.insert.delete这些操作的时候,系统会自动调用执行该表上对应的触发器.SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create.alter.drop语句.   常见的触发器有三种:分别应用于Inse