数据访问

1spirng对dao的支持

spring的DAO异常体系。spring在org .springframework.dao包中提供了一套完整优雅的DAO异常体系。都继承了DataAccessException,而DataAccessException本身继承了NestedRuntimeExcepiton.异常以嵌套的方式封装了源异常。可以通过getCause()方法获取原始的异常信息。

 

JDBC的异常转换器。

jdbc 抛出的异常SQLException拥有两个代表异常具体原因的属性。错误码和sql状态码,spring 可以根据错误码和sql状态码将sqlexcepiton转成spring dao异常体系的异常。

在org.springframework.jdbc.support包中定义了SQLExcepitonTranslator接口,改接口的两个实现类。SQLErrorCodeSQLexceptionTranslatro和SQLStateSQLExceptionTranslator,

 

 

其他持久技术的异常转换器。

hibernate3.0  seesionfactoryuitils

 jpa  entitymanagerfactoryuitlis

 

常用jdbc数据库访问操作流程是:

1、准备资源 连接,

2、启动事务。

3、在事务中执行具体数据库访问操作,

4、提交、回滚事务,

5、关闭资源,处理异常。


spring 将这个相同的数据访问流程固化到模板中,并将数据访问中固定和变化的部分分开,同时保证模板类线程安全,以便多个数据访问线程共享同一个模板实例。固定的部分在模板中已经准备好,而变化的部分通过回调接口开发出来。用于定义具体数据访问和结果返回的操作。这样,我们只要编写好回调接口,


spring 还提供对应持久化技术的支持类。列如:HibernateDaoSupport ,提供两方法,方便dao的实现:

 1、public fianl HibernateTemplate getHibernateTermplate();

 2、public final void setSessionFactory(SeesionFactory sessionFactory);

其中setSeesionFactory 用来接收spring的AppliactionContext的依赖注入,可以接收配置在spirng的sessionfactory的实例,getHibenateTemplate方法则用来更具有获得的sessionfactory产生的session。


其实spring+hibernate访问数据库有以下几种方式

1、注入sessionfactory

在spirng配置文件中,对dao注入sessionfaoctry 比较简单,

如:

<bean id="Userinfodao" class="xxx.xx.userinfodaoImpl">

  <property name="seesionfaocty" ref="sessionfactory"></property>

</bean>

这里的sessionfactory注入不是给类的,而是给继承hibernateDaoSupport类的sessionFactory


2、注入hibernateTemplate

这种方法本质跟上面的ssesionfactory一样,

<bean id="hibernateTemplate" class="org.springframework,org.hibernate3.hibernateTemplate">

 <property name="sessionfactory">

  <ref bean="seesionfactory">

</property></bean>


3、注入jdbcTemplate

   这种方法适合那些不喜欢hibernate的save、update等方法,喜欢自己写的N人,有时候jdbctemplate查询的效率会很高。


数据源:

c3p0跟dbcp比较,感觉c3p0好,因为它可配置的参数多,不过最关心的是,最大连接数,初始链接数,超时回收连接数,设置prpstatment的缓存。

spring的事务

  数据库事务,必须同时满足4个特性。原子性、一致性、隔离性、持久性、


数据并发的问题。

拥有多个访问客户端。并发访问数据库。数据库相同数据可能同时被多个事务访问。如果没有采取必要隔离措施,就会导致这种并发问题。破坏数据完整性。这些问题可以归结为5类,包括3类数据读问题(脏读、不可重复读、幻象读)以及2类数据更新问题(第一类丢失更新、第二类丢失更新),


并发事务处理时产生的意外情况

1.丢失更新(Lost Update) 
事务1:更新一条记录。 
事务2:更新事务1处理中的记录。 
事务1:调用commit进行提交。 
事务2:调用commit进行提交。 
此时事务1所做的修改完全被事务2的修改覆盖,称为丢失更新。 
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。因为每个事务都不知道其它事务的存在,最后的更新将重写由其它事务所做的更新,这将导致数据丢失。


2.脏读(Dirty Read):一个事务读取到了另外一个事务没有提交的数据,所以你可能会看到一些最后被另一个事务回滚掉的数据。 
事务1:更新一条记录。 
事务2:读取事务1更新的记录。 
事务1:调用commit进行提交或调用rollback进行回滚。 
此时事务2读取到的数据是保存在数据库内存中的数据,称为脏读。读到的数据为脏数据 
详细解释:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。


3.不可重复读(NonRepeatable Read):在同一事务中,两次读取同一数据,得到内容不同。即一个事务再次读取之前曾经读取过的数据时,发现该数据已经被另一个已提交的事务修改。 
事务1:查询一条记录。 
事务2:更新事务1查询的记录。 
事务2:调用commit进行提交。 
事务1:再次查询上次的记录。 
此时事务1对同一数据查询了两次,可得到的内容不同,称为不可重复读。


4.幻读(Phantom Read):同一事务中,用同样的操作读取两次,得到的记录数不相同。即一个事务重新执行一个查询,返回一批符合查询条件的记录,但这些记录中包含了因为其它最近提交的事务而产生的新记录。 
事务1:查询表中所有记录 
事务2:插入一条或一批记录 
事务2:调用commit进行提交 
事务1:再次查询表中所有记录 
此时事务1两次查询到的记录是不一样的,称为幻读 
详细解释:幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

数据库锁机制

 提供5中锁机制,不过因为复杂,所以用配置方式来配置。


Threadlocal   不是线程,而是线程的一个本地化对象。当工作于多线程中的对象使用threadlocal维护变量,保证每个变量的线程分配一个独立的变量副本。

可以这么理解:threadlocal 绑定了一个可能会被多线程访问的实例对象中的一个变量。


一般的web应用划分三个层次,在不同层编写对应的逻辑,下层通过接口向上层开发功能调用。在一般情况下, 从接收请求道返回响应所经过的所有程序调用都属于一个线程















































































































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值