posts - 78, comments - 34, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

     摘要: (转自:http://hi.baidu.com/%C9%AE_%CC%C6/blog/item/9e2a8b0887008a8ad0581b3d.html) 这是转载自一个兄弟的,写的比较细致,受益颇多!我只是针对图片进行了修改,使它看起来逻辑清晰一些。 十分感谢这位兄弟!        Java平台提供了一个全新的集合框架。...  阅读全文

posted @ 2009-12-06 21:48 長城 阅读(422) | 评论 (0)编辑 收藏

         今日学习的是在Oracle中使用简单的查询语句,与“2009-11-29传智播客 数据库——数据库入门[mysql]”学习的内容差不多,不知写些什么好了。现在学习的都是单表查询,后天应该就开始学习多表操作了。

 

         Oracle中有个虚拟表“DUAL”,说是虚拟,只是这个表不需要用户创建。在数据库里默认就有的,它有什么用途?用一句话概括一下:只是不是针对某表记录的操作,就需要这个表来完成!比如,打印当前系统时间就需要:“select sysdate from dual”,但在MySQL等数据库中确不需要这样,在MySQL中直接使用“select now();”即可。

 

         今日老冯讲解的Oracle函数比较简单,但也让我感觉到Oracle的强大。比如说有一个“decode”函数,说是函数更像是“switch catch”语句。老冯有个例子,要按照职位给员工涨工资:

SELECT   last_name,salary,

      decode(job_id,

          '总经理',1.15*salary,

          '副总经理',1.10*salary,

          salary)  工资

FROM employees;

 

         可见它的强大了吧!下面列一下日期时间与文本互转的格式和数字与文本互转的格式:

期日格式:

格式控制符

描述

YYYY  YYY YY

以数字表示全年(分别代表4位、三位、两位)的数字年

YEAR

年的拼写

MM

两位数字月

MONTH

月的全拼

MON

月名称的缩写

DD

数字日

DAY

星期的全拼

D

星期中的第几天 

DY

表示三位缩写的星期

 

         注意:调用TO_DATE函数时,比如TO_DATE(“2009-12-05”,”yyyy-mm-dd”),其中第二个日期格式字符串必须与第一个参数的时间格式相同。

 

数字格式控制符:

数字格式控制符

描述

9

代表一位数字,如果当前位有数字,显示数字,否则不显示(小数部分仍然会强制显示)

0

强制显示该位,如果当前位有数字,显示数字,否则显示0

$

增加美元符号显示

L

增加本地货币符号显示(RMB)

.

小数点符号

,

千分位符号  3,000,000,000.00

 

         其他操作函数,就去下载了个Oracle函数大全吧!操作数据库这些语句,更多的就是练习了,练习的让自己很容易记下来。

 

         来传智播客学习的这段时间,让我感觉很好,充实了很多。真是物有所值,也搞不懂那些教一些基础知识加点高级内容的培训机构却要1万多。而且还是远程视频授课!真是越垃圾的学校越贵,广告做的真好!课间时,大家有与老冯谈论起大连的软件产业。只要做这行的都知道,大连的软件产业外包是重点,而且这个城市是出了名的收入低消费高。这些到也罢。要命的是,给日本人干活,那真叫苦力!似乎一点动脑子的东西都不愿意让你来做,做这种工作的人应该都不叫程序员吧。应该叫“打字”员,专门按照日本人写的文档来打代码。如果这种工作在中国过多,还到那里去发展什么自己的核心竞争力啊!不过没办法,人家愿意出钱。也有听说,日本人出的一个人月是2-3万人民币,但到程员手中却只有3000-5000元。呵呵!

 

         无论如何,学习结束后我还是想回到大连。我喜欢那里!

posted @ 2009-12-05 21:20 長城 阅读(350) | 评论 (0)编辑 收藏

     摘要:          从今日起连结四天Oracle,由冯威老师授课。由于以前没有接触过Oracle数据库,所以上午讲解的Oraclae数据库的一些专业名词,让我有点措手不及。不过没关系,回家看一下就可以了。上午的内容比较枯燥,下午还好。下午讲解在Oracle数据库中使用SQL语句,这相对轻松些。SQL语句与前两天学习的在M...  阅读全文

posted @ 2009-12-04 22:46 長城 阅读(315) | 评论 (0)编辑 收藏

         我对IO流的理解上并没什么问题,但前一片段上课时有经常使用到IO流。发现自己对JAVAIO流没有系统的概念,JAVAIO流的要类是InputStreamOutputStream,这两个类的子类较多,而且还有一部分的包装类。SO,我要对JAVAIO流有一个系统的学习。

JAVA IO 全视图:

JAVAIO 

InputStream部分:

         InputStream,它是一个抽象类,所示所有输入流的的超类。它包含了输入流的基本操作。

         AudioIntpuStream,音频输入流对应的输出。结合AudioSystem可以实现:

1.        从外部音频文件、流或 URL 获得音频输入流

2.        从音频输入流写入外部文件

3.        将音频输入流转换为不同的音频格式

ByteArrayInputStream,字节数据输入流。字面的翻译。它包含了一个缓冲区,该缓冲区从输入游戏中读取字节。因为数据已经读入到缓冲区中,所以关闭流对它无效,仍然可以调用它的方法而不会抛出异常。

FileInputStream,文件输入流。从文件中获取输入字节,包含对文件流的特殊方法。如果要读取字符流,可以使用FileReader

PipedInputStream,管道输入流。用于线程间的通讯,但不要在同一个线程中使用管道输入流和输出流,这样可能造成线程死锁。

SequenceInputStream,输入流的逻辑串联。它将多个输入流串联到一起读取。比如它串联了输入流AB,当读取到A的结尾时,便从B流中接着读取。

StringBufferInputStream,与ByteArrayInputSteam类同,ByteArrayInputStream用于处理字节,而StringBufferInputStream用于处理字符。

ObjectInputStreamJava对象输入流。实现将对象从输入流中读取。比如将ObjectOutputStreamFileOutputStream结合使用,将JAVA对象序列化后保存到文件。然后再使用FileInputStreamObjectInputStream将文件中被序列化的JAVA对象反序列化回来到程序中。也可以在远程通讯中使用对象流传输JAVA对象,这个比较高级。

FilterInputStreamJDK帮助文档中说它只是简单的重写将所有对输入流的操作传递给它所包含的InputStream输入流。嗯,其实它是一个Decorate模式的超类。从它继承了一些子类,用于提供一些额外的功能,向下看。

         BufferedInputStream,对InputStream增加了缓存功能。以更好的支持markreset方法。

CheckedInputStream,校验输入流。可用于验证输入数据的完整性。与Checksum配合使用。

CipherInputStream,解密输入流。与Cipher配合使用。CipherOutputStream是加密输出流。对数据进行加解密使用。

DigestInputStream,摘要输入流。这个比较少见,棱一看JDK手册,不太了解。不过数据摘要是用于安全通讯或数据完整证验证的。哦,它与MessageDigest配合使用,可见JAVA IO设计者的用心!

LineNumberInputStream,行号输入流。此类已过时。它假定输入流是字符流,它调用InputStream的方法并将\n\r统一转换成一个\n。每读到一个换行时,便将行号加1,初始行号为0。此类不深入研究了!

ProgressMonitor,进度监视输入流。用于监视用户读取的进度,如果这个流很大。它会自动弹出进度提示窗口,用户可以点击“Cancel”按钮,取消读取。这个也实JAVAIO给实现了,比较人性化!

PushBackInputStream,推回输入流。就是可以将从输入流中读取的数据,调用unread方法将数据推回到输入流中,也可以将其他数据推进去。JDK手册中举了一个例子说,将标识符字符读取后,可以推回到输入然,然后重复读取,在哪里需要这样的应用呢?

DataInputStream,数据输入流。可以以与机器无关方式从底层输入流中读取基本JAVA数据类型。

InflaterInputStream 解压缩输入流。解压缩以“deflate”压缩格式的流过滤器。它与Inflater配合使用,Inflater使用流行的ZLIB压缩库。

         GZipInputStreamGZip解压缩输入流。解压缩以“GZip”压缩格式的流过滤器。

         ZipInputStreamZip解压缩输入流。解压缩以“Zip”压缩格式的流过滤器。

         JarInputStreamJar解压缩输入流。可以读取Jar文件中的内容。其实Jar的压缩格式就是Zip格式。但它比Zip多了一个Manifest条目。Manifest 可用于存储有关 JAR 文件及其条目的元信息。关于Manifest,可以查看JDK手册。

         OKOutputStream在此就不一一列出了。因为OutpuStream中子类与InputStream中的子类相对应。但OutpuStream不完全具有与InputStream中的子类对应的类。因为没必要,比如AudioInputStream,没有与之对应的AudioOutputStream,我们需要读取指定格式的音频即可。如果想写出音频数据直接用FileOutputStream即可!        

         Java中还有WriterReader两个超类,主要用于处理字符流,这个比较简单就不在此做介绍了。OK

posted @ 2009-12-03 22:48 長城 阅读(393) | 评论 (0)编辑 收藏

JAVAIO

posted @ 2009-12-03 16:22 長城 阅读(270) | 评论 (0)编辑 收藏

Today is JDBC高级部分,课程的主要内容有连接池与事务。这都是在应用开发中比较常用,比较重要的。

一、使用配置文件优化JDBCUtil,使用工厂模式隔离DAO层:

昨天有说过将对数据库获取连接和释放的操作单封装到一个类中,如:

import java.sql.*;
import cn.itcast.cc.exception.JDBCUtilException;

/**
 * JDBC工具类
 * 
 * @author Administrator
 * 
 */
public class JDBCUtil {
	// 连接数据库时所需要的参数
	private static String url = "jdbc:mysql://localhost:3306/jdbc";
	private static String username = "root";
	private static String password = "root";
	// 类被加载时就加载驱动
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 获取连接
	public static Connection getConnection() throws JDBCUtilException {
		try {
			return DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			throw new JDBCUtilException(e);
		}
	}

	// 释放连接等资源,下面是一种健康的释放方式
	public static void release(ResultSet rs, Statement sta, Connection conn)
			throws JDBCUtilException {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				throw new JDBCUtilException(e);
			}
			rs = null;
		}

		if (sta != null) {
			try {
				sta.close();
			} catch (SQLException e) {
				throw new JDBCUtilException(e);
			}
			sta = null;
		}

		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				throw new JDBCUtilException(e);
			}
			conn = null;
		}
	}
}

从上面我们看到其中装载数据库驱动和获取数据库连接的代码:

Class.forName("com.mysql.jdbc.Driver");

DriverManager.getConnection(url, username, password);

我们使用了固定的url,它是一个成员。在以后的开发中,如果要使用其他的数据库或者数据库的用户名密码被改变了,我们还需要手动的修改上边的代码,重新编译。这是一种不良的设计方法,为了使我们的代码与数据库分离,我们可以将这些参数配置到配置文件中。这样在需要使用时去读取配置文件中的对应值即可。以后换数据库或更改了用户名,直接修改一下配置文件即可。

昨天有提到过DAO层,DAO层专门用于处理对数据库的CURD操作等,比如,添加用户、查找用户、修改用户、删除用户,我们可以把这些操作封装到一个类中(UserDao.java),它所处位置就是DAO层。比如,用于处理用户注册的Servlet,在这个Servlet中直接实例化一个UserDao对象。然后调用userDaoObj.add(userbean);方法即可实现用户的注册。

如果我想换一种数据存储方式,比如配置文件,我只将用户信息保存在配置文件中。这样我就需要修改UserDao.java,但有时又需要UserDao.java这个功能类怎么办?我只能重新创建一个专门处理配置文件数据的类(UserDaoPro.java)。这样我又需要修改Servlet中的代码,将实例化UserDao的代码修改为实例化UserDaoPro对象。那UserDaoPro与UserDao的接口是不是相同的呢?如果不相同麻烦就大了,JAVA是提倡使用接口编程的,就是为了实现接口的统一化。

可见,上面的这种实现方式是存在问题的。即使接口统一,我们还需要修改Servlet中的代码。此时工厂模式派上了用场,还记得工厂模式吧!是这样的:

1.定义一个UserDao接口,统一对用户操作的接口。

2.定义一个UserDaoFactory的工厂类,专门生产UserDao对象。

3. UserDaoFactory工厂从配置文件中读取实现了UserDao接口的类名称。使用此类生产产品——UserDao对象。

4.在Servlet中使用UserDaoFactory工厂来创建需要的UserDao对象。

这样就实现了DAO层与Servlet的完全分离!完美!

二、数据库连接池:

每当有一个新的连接发生时,数据库就需要创建一个Connection对象来处理连接。访问结束后,Connection对象被释放。数据库创建一个Connection对象,是十分耗时且消耗较大的服务器资源。试想,如果有500个用户同时访问数据库,数据库同时创建500个Connection将会是什么样子!因此,连接池这一技术诞生了。

连接池,在服务器加载WEB应用后。WEB应用会自动创建一个连接池,池中包含多个Connection对象。每当有新的连接请求时,便从这个池中拿出一个Connection对象用于处理连接,使用完成后,便还回给这个池子。下面代码为连接池的实现原理:

import java.io.*;
import java.lang.reflect.*;
import java.sql.*;
import java.util.*;
import javax.sql.DataSource;

/**
 * 自己编写的简单连接池类,单例模式实现。
 * 
 * @author Administrator
 * 
 */
public class JDBCUtil implements DataSource {
	private static LinkedList<Connection> conns = new LinkedList<Connection>();
	private static JDBCUtil myjdbcutil = new JDBCUtil();

	private JDBCUtil() {
		// 取配置文件
		InputStream in = JDBCUtil.class.getClassLoader().getResourceAsStream(
				"cn/itcast/cc/db/myjdbc.properties");
		// 装载配置文件
		Properties pro = new Properties();
		try {
			pro.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 取出配置项
		String driver = pro.getProperty("driverClassName");
		String url = pro.getProperty("url");
		String username = pro.getProperty("username");
		String password = pro.getProperty("password");
		int initialSize = Integer.parseInt(pro.getProperty("initialSize"));
		// 加载驱动,填充连接池
		try {
			// 常用的数据库,驱动类被加载时,都会自已加载驱动。
			Class.forName(driver);
			for (int i = 0; i < initialSize; i++) {
				conns.add(DriverManager.getConnection(url, username, password));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 返回单例的实例
	public static JDBCUtil getInstance() {
		return myjdbcutil;
	}

	public Connection getConnection() throws SQLException {
		if (conns.size() > 0) {
			final Connection conn = conns.pop();
			// 此处需要使用动态代理技术,因为返回的Connection对象在关闭时需要被收回到LinkedList中。
			// 动态代理,增强Connection.colse()方法,将它回收到LinkedList中。但不销毁!
			return (Connection) Proxy.newProxyInstance(JDBCUtil.class
					.getClassLoader(), conn.getClass().getInterfaces(),
					new InvocationHandler() {

						public Object invoke(Object proxy, Method method,
								Object[] args) throws Throwable {
							// 如果是close方法,则将conn回收到List中。
							if (method.getName().equals("close")) {
								conns.push(conn);
								return null;
							}
							return method.invoke(conn, args);
						}
					});
		}
		throw new RuntimeException("服务器忙,请稍后连接!");
	}
}

有很多服务器为用户提供了DataSource(数据源)的实现。DataSource中包含了连接池的实现。也有一些第三方组织单独提供了连接池的实现:DBCP、C3P0。所以,在以后的开发中,我们可以直接使用这些资源。

著名的DBCP比较常用,使用DBCP必须引入Commons-dbcp.jar和Commons-pool.jar。Tomcat中的连接池也是使用DBCP实现的。DBCP的使用非常简单:

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPUtil {
	private static DataSource ds = null;
	static {
		try {
			// 取配置文件
			InputStream in = JDBCUtil.class.getClassLoader()
					.getResourceAsStream(
							"cn/itcast/cc/db/dbcpconfig.properties");
			// 装载配置文件
			Properties pro = new Properties();
			pro.load(in);
			// 创建数据源
			ds = BasicDataSourceFactory.createDataSource(pro);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 获取连接
	public static Connection getConnection() throws SQLException {
		return ds.getConnection();
	}
}

 

其中的配置文件“dbcpconfig.properties”:

#连接设置

#驱动器

driverClassName=com.mysql.jdbc.Driver

#数据库连接URL

url=jdbc:mysql://localhost:3306/jdbc

#数据库用户名

username=root

#数据库密码

password=root

#初始连接池数量

initialSize=10

#最大连接数量

maxActive=50

#最大空闲连接

maxIdle=20

#最小空闲连接

minIdle=5

#超时等待时间以毫秒为单位 6000毫秒/1000等于60秒

maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]

#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。

connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。

defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。

#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)

defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。

#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE

defaultTransactionIsolation=READ_UNCOMMITTED

上面是直接使用Apache提供的DBCP实现的连接池,接下来看一下使用JNDI技术在Tomcat中配置连接池,在Tomcat服务的conf\context.xml文件中添加:

<Context>

<Resource name="jdbc/datasource" auth="Container"

type="javax.sql.DataSource" username="root" password="root"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/jdbc"

maxActive="8" maxIdle="4"/>

</Context>

Name: 对象在JNDI容器中的名称。

Auth:所使用的容器。

Type:对象类型。

Username:数据库用户名。

Password:数据库密码。

driverClassName:数据库驱动类。

url:连接数据库的URL。

maxActive:最大连接数。

maxIdle:最大空闲连接数。

注意其中的数据库驱动,对应的jar包必须放置到Tomcat目录下的lib目录中。这样服务器才能找得到。

在WEB应用中获取数据库连接的代码:

// 初始化JNDI环境

Context initCtx = new InitialContext();

// 获取JNDI容器

Context envCtx = (Context) initCtx.lookup("java:comp/env");

// 获取数据源

DataSource dataSource = (DataSource)envCtx.lookup("jdbc/datasource");

// 获取数据库连接

dataSource.getConnection();

JNDI是一个对象容器,服务器根据配置文件提供的信息。创建这些对象,并按照指定的名称保存在容器中。WEB应用,无论在何处都可以根据名称获取在JNDI容器中的对象。

三、数据库事务管理:

什么是事务?老方有这样的面试题。事务指逻辑上的一组操作,这组操作要不全部生效,要不全部失效。在控制台中操作事务的命令:

start transaction 开启事务

Rollback 回滚事务

Commit 提交事务

set transction isolation level 设置事务隔离级别

select @@tx_isolation 查询当前事务隔离级别

事务的特性(ACID),这在面试中是比较常见的。老方一再强调,一定要记下来!OK,让我们看一看。

事务的原子性(Automicity),它更像是事务的定义。就是逻辑上的一组操作,不可分割,要么全部生效,要么全部失效。

事务的一致性(Consistency),老方的PPT有中说:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如,银行转账,A-B。A账户中减少100元,B帐户中增加一百元。这看起来比较好理解,但让我有点疑问的是,如果从数据库中删除一个用户呢?难道不用事务处理吗?所以我对这个一致性的理解除了老方说的,还有只要事务处理符合正确的逻辑,就是一致性。

隔离性(Isolation),如果多个用户同时访问数据库,同时访问一张表。这样会造成一些访问错误,所以有了隔离性这一定义。将多个并发事务之间要相互隔离。

持久性(Durability),事务一旦被提交,它对数据库中数据的改变是永久性的,无论其他操作或数据库故障不会对它有任何影响。

在JDBC中使用事务的语句:

// 开启事务

conn.setAutoCommit(false);

// 回滚事务

conn.rollback();

// 提交事务

conn.commit();

// ...

// 设置保存点

sp = conn.setSavepoint();

// 回滚到指定保存点

conn.rollback(sp);

方老师使用了一个经典的案例,来讲解事务处理——银行转账系统!

例,用户A转账10000元给用户B。应该是A账户中减少10000元,B账户中增加10000元。那么在A提交了10000元后,数据库发生问题(比如断电),那B帐户增加10000元的语句还没有执行。使用事务可以很好解决这一问题:

1. 开启事务

2. A帐户减少10000元

3. 中间发生错误,回滚事务

4. B帐户增加10000元

5. 提交事务

OK,在上同这一过程中,如果没有执行到第5步。数据库的内容就不会发生改变。在此有必要解释一下回滚事务,回滚事务在提交事务后执行没有什么效果,回滚事务在提交事务之前执行,会擦除在开启事务之后执行的SQL语句。

上面是针对单一事务进行的处理,在并发事务中会遇到一些问题。设置事务的隔离级别可以很好的解决这一问题。

首先我们来看一下并发事务容易产生的问题:

脏读:

例,用户A账户减少10000元,用户B账户增加了10000元,但A还没有提交事务。此时,B去查询它的账户发现A已经给自己转账了10000元。然后,A回滚了事务。B被A给骗了,这就是脏读,B读到的是未提交的数据。我虽对数据库事务的实现原理不了解(事务是通过日志处理的),我打个比方就更好理解这一原因了。数据库对所有用户维护了一个虚表,在开启事务中,提交事务前对数据的修改,都是修改的虚表,用户查询的也是虚表的内容,当执行了提交事务操作后,将虚表中被修改的内容保存到数据库。实际技术细节就不深入了!

不可重复读:

例,用户A原账户内容为100万元,此时银行将数据显示到电脑屏幕和保存到文件中。银行工作人员在电脑屏幕上看到的是100万元,但此时,用户A向账户里又存了100万元。结果保存到文件的是200万元。到是100万元还是200万元?工作人员有些迷惑。与脏读相反的是,脏读是读取了前一事务未提交的数据,不可重复读读取的是前一事务提交了的事务。注意,不可重复读针对的是某一记录!

虚读:

例,银行要统计A的报表。A的账户中有200万元,屏幕上报表显示的总额是200万元,此时,用户A向账户中又存入了100万元。报表打印出来的总额就是300万元。工作人员一对比,到底哪个是正确的?注意,虚读针对的是整个表。

不可重复读和虚读,有点难理解。这看起来不是什么问题,如果发生这一问题,工作人员就刷新一下表呗!如果工作人员处理的是1万个用户的报表,同时不幸运的是这1万个用户都发生了虚读的问题。那工作人员能受了吗?你可能还会说那就以打印的报表为准呗!问题是,可能屏幕上的那个才是正确的,这样就要重新打印报表。所以为了使问题得以简单的解决,事务的隔离性发挥了它的作用!

处理上边的三种并发事务产生的问题,数据库定义了四种隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。

Repeatable read:可避免脏读、不可重复读情况的发生。

Read committed:可避免脏读情况发生。

Read uncommitted:最低级别,以上情况均无法保证。

Serializable,最高安全级别。设置了此级别,当一个事务访问了某一表时,此表就会被封死。其他事务对此表的访问就会被挂起,直到上一事务提交后才执行一个事务。OK,这看起来十分容易理解。

Repeatable read,让我再小深入一下,当每个事务线程访问同一表时,数据库针对每个线程维护了一张虚拟表。此时各线程看到的都是原始的数据内容,对表数据的修改相互不发生影响,即使事务被提交了。数据库可能为每个线程维护了一张虚拟表吗?当然不可以,我想这只是为了便于理解。技术细节不深入研究!

Read committed,数据库对每个用户的查询显示的都是原始内容(真实内容)。如果某些用户对此表的事务没有提交就不会影响原始内容。所以其他用户查看到的都是原始内容或提交了的数据内容。

Read uncommitted,这个就不多说了。

今天的内容也就事务的隔离性有些难度吧!一般也不会去用那最高安全级别,这一级别在银行中比较常用。

正如老方所说,是不是感觉越学越简单了!确实如此,我想大家应该也对此有感觉。不知不觉明天又休息了!

加油!

posted @ 2009-12-02 23:20 長城 阅读(752) | 评论 (1)编辑 收藏

仅列出标题
共8页: 上一页 1 2 3 4 5 6 7 8