LearnSpringinspring(四)

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  四、Spring中的事务控制

  Bromon原创 请尊重版权

  Spring和EJB一样,提供了两种事务管理方式:编程式和声明式。在考试系统中我们将使用声明式的事务管理,这是spring推荐的做法。使用这种方式可以体验到spring的强大便捷,而且我们无须在Dao类中编写任何特殊的代码,只需要通过配置文件就可以让普通的java类加载到事务管理中,这个意义是很重大的。

  Spring中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,由于接口是延迟实例化的,spring在这段时间内通过拦截器,加载事务切片。原理就是这样,具体细节请参考jdk中有关动态代理的文档。本文主要讲解如何在spring中进行事务控制。

  动态代理的一个重要特征是,它是针对接口的,所以我们的dao要通过动态代理来让spring接管事务,就必须在dao前面抽象出一个接口,当然如果没有这样的接口,那么spring会使用CGLIB来解决问题,但这不是spring推荐的方式,我们也不做讨论。

  参照前面的例子,我们为StudentManager.java定义一个接口,它的内容如下:

  /*

  *创建日期2005-3-25

  */

  packageorg.bromon.spring.examer.student;

  importjava.util.List;

  importorg.bromon.spring.examer.pojo.Student;

  /**

  *@authorBromon

  */

  publicinterfaceStudentManagerInterface

  {

  publicvoidadd(Students);

  publicvoiddel(Students);

  publicvoidupdate(Students);

  publicListloadAll();

  publicStudentloadById(intid);

  }

  StudentManager也应该做出修改,实现该接口:

  publicclassStudentManagerextendsHibernateDaoSupportimplementsStudentManagerInterface

  现在需要修改配置文件,用于定义Hibrenate适用的事务管理器,并且把sessionFactory注入进去,同时还需要通过注册一个DefaultTransactionAttribute对象,来指出事务策略。其中sessionFactory的定义已经在本文的第三章中说明。

  首先定义一个Hibernate的事务管理器,让它来管理sessionFactory:

 

 

 

 

 

  下面定义事务管理策略,我们希望把策略定义在方法这个级别上,提供最大的灵活性,本例中将add方法定义为:PROPAGATION_REQUIRES_NEW,这可以保证它将始终运行在一个事务中。

 

 

 

 

  PROPAGATION_REQUIRES_NEW

 

 

 

 

  我们不仅可以为add方法定义事务策略,还可以定义事务隔离程度和回滚策略,他们以逗号隔开,比如我们的add事务可以定义为:

 

  PROPAGATION_REQUIRES_NEW,-ExamerException

 

  这个事务策略表示add方法将会独占一个事务,当事务过程中产生ExamerException异常,事务会回滚。

  Add/update/del都是写入方法,对于select(读取)方法,我们可以指定较为复杂的事务策略,比如对于loadAll()方法:

 

  PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly

 

  该事务的含义为,loadAll方法支持事务,不会读取未提交的数据,它的数据为只读(可提高执行速度)。

  如你所见,我们的StudentManagerInterface接口中还有一个loadById(intid)方法,也许我们将来还会有很多的loadByXXXX的方法,难道要一一为他们指定事务策略?太烦人了,他们应该和loadAll()一样,所以我们可以使用通配符,定义所有的loadXXXX方法:

 

  PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly

 

  现在可以定义事务管理器:

 

 

 

 

 

 

 

 

 

 

 

  这个bean的外观是一个接口(StudentManagerInterface),我们指出了它的具体实现(studentManager),而且为它绑定了事务策略。在客户端使用的时候,获得对象是StudentManagerInterface,所有的操作都是针对这个接口的。测试代码并没有改变,我们虽然修改了很多地方,加入了事务控制,但是客户端并没有受到影响,这也体现了spring的一些优势。测试代码如下:

  publicvoidtestAdd()

  {

  ApplicationContextctx=newClassPathXmlApplicationContext("springConfig.xml");

  StudentManagersm=(StudentManager)ctx.getBean("studentManager");

  Students=newStudent();

  s.setId(1);

  s.setName("bromon");

  s.setPassword("123");

  s.setGrade(1);

  s.setSex(0);

  sm.add(s);

  }

  通过以上的代码可以看出,spring可以简单的把普通的javaclass纳入事务管理,声明性的事务操作起来也很容易。有了spring之后,声明性事务不再是EJB独有,我们不必为了获得声明性事务的功能而去忍受EJB带来的种种不便。

  我所使用的mysql是不支持事务的,你可以更换使用PostgreSQL,有了spring+hibernate,更换db并不像以前那样恐怖了,步骤很简单:

  1、添加PostgreSQL的jdbc驱动

  2、修改dataSource配置,包括驱动名称、url、帐号、密码

  3、修改sessionFactory的数据库dailet为net.sf.hibernate.dialect.PostgreSQLDialect

  4、修改hbm.xml中的主键生成策略为increment

  所有的修改都在配置文件中完成,业务代码不需要任何修改,我很满意,Howaboutu?

  附A pring中的所有事务策略

  PROPAGATION_MANDATORY

  PROPAGATION_NESTED

  PROPAGATION_NEVER

  PROPAGATION_NOT_SUPPORTED

  PROPAGATION_REQUIRED

  PROPAGATION_REQUIRED_NEW

  PROPAGATION_SUPPORTS

  附B Spring中所有的隔离策略:

  ISOLATION_DEFAULT

  ISOLATION_READ_UNCOMMITED

  ISOLATION_COMMITED

  ISOLATION_REPEATABLE_READ

  ISOLATION_SERIALIZABLE

  下一篇:spring中的jms

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
阅读更多
个人分类: ajax xml
想对作者说点什么? 我来说一句

LearnSpringinspring(三)

zgqtxwd zgqtxwd

2008-05-01 06:27:00

阅读数:106

LearnSpringinspring(二)

zgqtxwd zgqtxwd

2008-05-01 06:31:00

阅读数:170

LearnSpringinspring(一)

zgqtxwd zgqtxwd

2008-05-01 06:32:00

阅读数:164

人工智能四子棋AI

2013年06月23日 23KB 下载

四旋翼MATLAB仿真控制

2016年03月27日 2.66MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭